在栈/堆上生成对象

在栈/堆上生成对象

c++中,有时我们希望某种类型的对象有“自我析构”的能力,即能够"delete this",这样就要求该类型的对象被分配于堆中。另外还可能在某些场景下必须保证某一类型绝不会发生内存泄漏,即需要没有任何一个该类型的对象从堆中分配出来。

在堆中生成对象

我们知道非堆对象会在其定义点自动构造,并在其寿命结束时自动析构,所以要保证对象在堆中生成,只要让那些被隐式调用的构造函数和析构函数不合法就可以了。

更具体来说,最直接的方法是将构造函数和析构函数都声明为private,但由于一个类可能有许多个构造函数,其中包括copy constructor,以及default constructor,类的作者必须记住将他们都每一个都声明为private,这样比较麻烦。更简单的方法是使析构函数为private,而构造函数仍为public。例如,heap-based 类:

class HeapBased
{
public:
	HeapBased(){m_value = 0;}
	HeapBased(int value);
	HeapBased(const HeapBased& rhs);

	void destroy()const
	{
		delete this;
	}
private:
	~HeapBased();  //将dtor声明为private
private:
	int m_value;
};

生成对象的操作:

	HeapBased implicitObj;  //隐式调用ctor,在对象的dtor稍后被隐式调用后会出错
	HeapBased* pHeadBased = new HeapBased(); //succ

	...
        
	delete pHeadBased; //error! 试图调用private dtor,
	pHeadBased->destroy(); //succ

但是还有一点需要考虑的,就是在存在继承和包含关系时,private dtor 会导致派生类出错。那么我们就需要在存在继承关系时,令析构函数为protected,而在存在包含关系时,将内含HeapBased对象变为包含一个指向HeapBased对象的指针。

class HeapBased
{
public:
	HeapBased(){m_value = 0;}
	HeapBased(int value);
	HeapBased(const HeapBased& rhs);

	void destroy()const
	{
		delete this;
	}
protected:
	~HeapBased();  //将dtor声明为private
private:
	int m_value;
};

class DerivedHeapBased : public HeapBased  //可以正常取用protected members
{
	...
};

class ContainHeadpBased
{
	...
private:
	HeapBased* m_heapBased;
};

禁止对象生成于heap内

想要阻止将对象在堆内生成的操作,由于这些对象总是以new产生出来,我们可以让调用new的操作不合法。虽然我们不能够影响new operator 的能力(由语言内建),但是我们可以利用 new operator 总是调用 operator new 的原则,而operator new 是我们可以自行声明的。即我们可以将其声明为private。

例如,对不不希望将对象生成于heap 内的场景:

class NoneHeap
{
private:
	static void* operator new(size_t size);
	static void operator delete(void *ptr);
};

使用该类时:

NoneHeap pNoneHeap;			//succ
static NoneHeap pNoneHeap2;	//succ
NoneHeap* pNoneHeap3 = new NoneHeap();//error! 企图调用private operator new

除此之外,如果也需要禁止 由NoneHeap对象所组成的数组在堆内生成,可以将 operator new[] 和 operator delete[]也声明为 private。

而对于存在继承和包含关系的场景,由于 operator new 和 operator delete 都会被继承,所有派生类如果另外没有声明这些函数为public,那么便会继承这两个函数的private版本,即与父类的表现一致。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值