C++:设计一个类,只在堆上 / 栈上创建对象

本文探讨如何设计C++类,确保对象只在堆或栈上创建。通过私有化构造函数并提供静态接口,限制堆或栈上的对象创建。在C++98和C++11中,采用不同的方法封杀拷贝构造函数和阻止堆分配,但全局对象仍可能创建。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设计一个类,只在堆上创建对象

class HeapOnly
{
public:
	static HeapOnly* GetHeapObj()
	{
		return new HeapOnly;
	}
private:
	//构造函数私有
	HeapOnly()
	{}
	//C++98:拷贝构造函数只声明不实现,并且声明成私有的
	HeapOnly(const HeapOnly&);
	//C++11:拷贝构造函数delete
	HeapOnly(const HeapOnly&) = delete;
};
int main()
{
	HeapOnly* obj = HeapOnly::GetHeapObj();//产生堆上的对象
}

思路分析:

  1. 构造函数要定义为私有的,因为调用构造函数产生的对象都在栈上
  2. 但是构造函数私有之后,对象new不出来了,因此要在类里面提供接口GetHeapObj,然后直接返回new出来的对象,这样产生的对象就在堆上
  3. 但是要调用这个GetHeapObj接口的话只有通过对象才能调用,而我们不能调用构造产生对象,那么应该怎么办呢?那就是把这个接口定义为静态的,静态的成员函数不需要对象也可以调用。
  4. 那又出现一个问题,如果我们调用这个GetHeapObj接口然后成功的产生了一个堆上的对象,如果再调用拷贝构造函数又会产生栈上的对象。所以我们要把拷贝构造函数也封杀掉,那如果是在C++98中我们就把拷贝构造函数只声明不实现就可以了,如果是在C++11中我们可以使用delete将这个函数删除,像这样HeapOnly(const HeapOnly&) = delete;也是可以的。
  5. 把构造函数封杀了,因此全局的变量也不可以被定义,所以就只能在堆上创建对象了

设计一个类,只在栈上创建对象

方法一:
class StackOnly
{
public:
	static StackOnly GetStackObj()
	{
		return StackOnly();
	}
private:
	StackOnly()
	{}
};
int main()
{
	StackOnly obj = StackOnly::GetStackObj();
}

思路分析:

  1. 构造函数要定义成私有的,因为防止new创建出堆上的对象
  2. 在类里提供GetStackObj接口,直接返回栈上的对象
  3. 同时把GetStackObj接口设置为静态的,不用对象也可以调用
  4. 因为这样把构造函数封杀了,因此全局的变量也不可以被定义,所以就只能在栈上创建对象了
方法二(C++98)
class StackOnly
{
public:
	static StackOnly GetStackObj()
	{
		return StackOnly();
	}
private:
	void* operator new(size_t size);
	void operator delete(void* p);
};
int main()
{
	StackOnly obj = StackOnly::GetStackObj();
}

思路分析:
这里是针对C++98,可以把operator new和operator delete放在私有里,这样就不能创建出堆上的对象了,但是这里会有一个bug就是全局的对象可以被创建出来。

方法三(C++11)
class StackOnly
{
public:
	static StackOnly GetStackObj()
	{
		return StackOnly();
	}
	void* operator new(size_t size) = delete;
	void operator delete(void* p) = delete;
};
int main()
{
	StackOnly obj = StackOnly::GetStackObj();
}

思路分析:
这里是针对C++11,可以直接把operator new和operator delete用delete删除,这样就不会创建出堆上的对象,但是这里和方法二一样有一个bug就是全局的对象可以被创建出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值