详解C++中如何将构造函数或析构函数的访问权限定为private

2020-01-06 14:47:28王旭

        如果将构造函数设计成Protected,也可以实现同样的目的,但是可以被继承。
        另外如何保证只能在堆上new一个新的类对象呢?只需把析构函数定义为私有成员。
        原因是C++是一个静态绑定的语言。在编译过程中,所有的非虚函数调用都必须分析完成。即使是虚函数,也需检查可访问性。因些,当在栈上生成对象时,对象会自动析构,也就说析构函数必须可以访问。而堆上生成对象,由于析构时机由程序员控制,所以不一定需要析构函数。保证了不能在栈上生成对象后,需要证明能在堆上生成它。这里OnlyHeapClass与一般对象唯一的区别在于它的析构函数为私有。delete操作会调用析构函数。所以不能编译。
        那么如何释放它呢?答案也很简单,提供一个成员函数,完成delete操作。在成员函数中,析构函数是可以访问的。当然detele操作也是可以编译通过。


void OnlyHeapClass::Destroy() { 
  delete this; 
} 

        构造函数私有化的类的设计可以保证只能用new命令在堆中来生成对象,只能动态的去创建对象,这样可以自由的控制对象的生命周期。但是,这样的类需要提供创建和撤销的公共接口。
        另外重载delete,new为私有可以达到要求对象创建于栈上的目的,用placement new也可以创建在栈上。

补充:
1.为什么要自己调用呢?对象结束生存期时不就自动调用析构函数了吗?什么情况下需要自己调用析构函数呢?   
        比如这样一种情况,你希望在析构之前必须做一些事情,但是用你类的人并不知道, 那么你就可以重新写一个函数,里面把要做的事情全部做完了再调用析构函数。 这样人家只能调用你这个函数析构对象,从而保证了析构前一定会做你要求的动作。

2.什么情况下才用得着只生成堆对象呢? 
        堆对象就是new出来的,相对于栈对象而言。什么情况下要new,什么情况下在栈里面 提前分配,无非就是何时该用动态,何时该用静态生成的问题。这个要根据具体情况具体分析。比如你在一个函数里面事先知道某个对象最多只可能10个,那么你就可以 定义这个对象的一个数组。10个元素,每个元素都是一个栈对象。如果你无法确定数 字,那么你就可以定义一个这个对象的指针,需要创建的时候就new出来,并且用list 或者vector管理起来。