不少状况下要求当前的程序中只有一个object。例如一个程序只有一个和数据库的链接,只有一个鼠标的object。一般咱们都将构造函数的声明置于public区段,假如咱们将
其放入private区段中会发生什么样的后果?这意味着什么?
当咱们在程序中声明一个对象时,编译器为调用构造函数(若是有的话),而这个调用将一般是外部的,也就是说它不属于class对象自己的调用,假如构造函数是私有的,
因为在class外部不容许访问私有成员,因此这将致使编译出错。
然而,对于class自己,能够利用它的static公有成员,由于它们独立于class对象以外,没必要产生对象也可使用它们。
此时由于构造函数被class私有化,因此咱们要建立出对象,就必须可以访问到class的私有域;这一点只有class的成员能够作获得;但在咱们建构出其对象以前,怎么能利用它
的成员呢?static公有成员,它是独立于class对象而存在的,“咱们”能够访问获得。假如在某个static函数中建立了该class的对象,并以引用或者指针的形式将其返回(这里不
以对象返回,主要是构造函数是私有的,外部不能建立临时对象),就得到了这个对象的使用权。
下面是例子:
class OnlyHeapClass
{
public:
static OnlyHeapClass* GetInstance()
{
// 建立一个OnlyHeapClass对象并返回其指针
return (new OnlyHeapClass);
}
void Destroy();
private:
OnlyHeapClass() { }
~OnlyHeapClass() {}
};
int main()
{
OnlyHeapClass *p = OnlyHeapClass::GetInstance();
... // 使用*p
delete p;
return 0;
}程序员
这个例子使用了私有构造函数,GetInstance()做为OnlyHeapClass的静态成员函数来在内存中建立对象:因为要跨函数传递而且不能使用值传递方式,因此咱们选择在堆上
建立对象,这样即便getInstance()退出,对象也不会随之释放,能够手动释放。
构造函数私有化的类的设计保证了其余类不能从这个类派生或者建立类的实例,还有这样的用途:例如,实现这样一个class:它在内存中至多存在一个,或者指定数量个
的对象(能够在class的私有域中添加一个static类型的计数器,它的初值置为0,而后在GetInstance()中做些限制:每次调用它时先检查计数器的值是否已经达到对象个数的
上限值,若是是则产生错误,不然才new出新的对象,同时将计数器的值增1.最后,为了不值复制时产生新的对象副本,除了将构造函数置为私有外,复制构造函数也要特别
声明并置为私有。
若是将构造函数设计成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管理起来。 --------------------------------------------------------------------------------------------------------------------------------- 类中“私有”权限的含义就是:私有成员只能在类域内被访问,不能在类域外进行访问。 把析构函数定义为私有的,就阻止了用户在类域外对析构函数的使用。这表如今以下两个方面: 1. 禁止用户对此类型的变量进行定义,即禁止在栈内存空间内建立此类型的对象。要建立对象,只能用 new 在堆上进行。 2. 禁止用户在程序中使用 delete 删除此类型对象。对象的删除只能在类内实现,也就是说只有类的实现者才有可能实现对对象的 delete,用户不能随便删除对象。若是用户想删除对象的话,只能按照类的实现者提供的方法进行。 可见,这样作以后大大限制了用户对此类的使用。通常来讲不要这样作;一般这样作是用来达到特殊的目的,好比在 singleton 的实现上。楼主可查找 singleton 的资料来了解它是怎么一回事。