1,设计只能在堆上分配的类
方法:将类的构造函数或者析构函数设置为protected(private会限制继承),迫使类对象在栈的构造时编译出错,并提供destroy接口
- using namespace std;
-
- class OnlyHeap
- {
- public:
- OnlyHeap()
- {
- cout<<"construct"<<endl;
- }
- void distory () const
- {
- delete this;
- }
- protected:
- ~OnlyHeap()
- {
- cout<<"destruct"<<endl;
- }
- };
- int main()
- {
- //OnlyHeap OnlyHeap; //会报错
- OnlyHeap* o=new OnlyHeap;
- o->distory();
- return 0;
- }
OnlyHeap * hash_ptr = new OnlyHeap() ;
... ... //对hash_ptr指向的对象进行操作
hash_ptr->destroy() ;
呵呵,是不是觉得有点怪怪的,我们用new创建一个对象,却不是用delete去删除它,而是要用destroy方法。
很显然,用户是不习惯这种怪异的使用方式的。所以,我决定将构造函数也设为private或protected。这又回到了上面曾试图避免的问题,即不用new,那么该用什么方式来生成一个对象了?我们可以用间接的办法完成,即让这个类提供一个static成员函数专门用于产生该类型的堆对象。(设计模式中的singleton模式就可以用这种方式实现。)让我们来看看:
class NoStackObject
{
protected:
NoStackObject() { }
~NoStackObject() { }
public:
static NoStackObject* creatInstance()
{
return new NoStackObject() ;//调用保护的构造函数
}
void destroy()
{
delete this ;//调用保护的析构函数
}
};
现在可以这样使用NoStackObject类了:
NoStackObject* hash_ptr = NoStackObject::creatInstance() ;
... ... //对hash_ptr指向的对象进行操作
hash_ptr->destroy() ;
hash_ptr = NULL ; //防止使用悬挂指针
现在感觉是不是好多了,生成对象和释放对象的操作一致了。
2,设计只能在栈上分配的类
方法:重载new和delete为private成员
- using namespace std;
- class OnlyStack
- {
- public:
- OnlyStack()
- {
- cout<<"构造"<<endl;
- }
- ~OnlyStack()
- {
- cout<<"析构"<<endl;
- }
- private:
- void* operator new (size_t t);
- void operator delete(void *ptr);
- };
- int main()
- {
- //OnlyStack * a = new OnlyStack; //会报错
- OnlyStack a;
- return 0;
- }