一、

类的构造函数一般是public的,但是也可以是private的。构造函数为私有的类有这样的特点:

<1>不能实例化:因为实例化时类外部无法访问其内部的私有的构造函数;

<2>不能继承:同<1>;

所以它可以控制用户实例化一个类对象。
实例化的这样的类的方法是在类中定义一个static方法或者一个友元,专门负责实例化工作。Java中的工厂方法常常采用这点。

二、

  我们知道,当我们在程序中声明一个对象时,编译器为调用构造函数(如果有的话),而这个调用将通常是外部的,也就是说它不属于class对象本身的调用,假如构造函数是私有的,由于在class外部不允许访问私有成员,所以这将导致编译出错。

你于是说:“哈哈。”我们制造了一个似乎无法产生对象的class.哦,当然,对于class本身,我们还可以利用它的static公有成员,因为它们独立于class对象之外,我们不必产生对象也可以使用它们。嗯,看来我们还是为带有私有构造函数的类找到了一个存在的理由。不过我们不应当满足于此,因为看上去应当还有发掘的余地。

    首先我们来认真看一下是不是真的无法创建出一个具有私有构造函数的类对象。“呃,可能未必。”你现在也许会这样说。这很好,让我们再来看看为什么,没错,因为构造函数被class私有化了,所以我们要创建出对象,就必须能够访问到class的私有域;但这一点“我们”是做不到的,那么,谁能做得到呢?class的成员可以做得到;但在我们建构出其对象之前,怎么能利用它的成员呢?噢,刚才我们刚刚提到了static公有成员,它是独立于class对象而存在的,当然,它也是公有的,“我们”可以访问得到。假如在某个static函数中创建了该class的对象,并以引用或者指针的形式将其返回(不可以以值的形式返回,想想为什么),我们就获得了这个对象的使用权。下面是例子:
class WonderfulClass
{
public:
static WonderfulClass* makeAnObject()
{
// 创建一个WonderfulClass对象并返回其指针 return (new WonderfulClass);
}
private:
WonderfulClass() { }
}; int main()
{
WonderfulClass *p = WonderfulClass::makeAnObject(); ... // 使用*p delete p; // Not neccesary here, but it's a good habit. return ;
}
  嗯,这个例子使用了私有构造函数,但它运行得很好:makeAnObject()作为WonderfulClass的静态成员函数,尽心尽责地为我们创建对象:由于要跨函数传递并且不能使用值传递方式,所以我们选择在堆上创建对象,这样即使makeAnObject()退出,对象也不会随之蒸发掉,当然,使用完之后你可不要忘了手工将它清除。

回到前面的思路:除了公有的static成员可以帮助我们访问私有域外,还有没有其它可以利用的“东西”?

噢,你一定想到了使用友元,完全正确。可以使用该类的友元函数或者友元类创建其对象,这里就不举例了。

我们知道没有人会无聊到无缘无故把一个class设为私有,然后再写一个和上面一模一样的makeAnObject()来让它的用户体验一下奇特的感觉。我们也不太相信这只是由于C++的设计原因而导致的一个“顺便的”“特殊的”“无用的”边角功能。它应当是有实际用途的。提醒一下,到了JAVA中你会更容易明白很多静态方法创建对象的原理!!!

嗯,例如,我们想实现这样一个class:它至多只能存在一个,或者指定数量个的对象(还记得标准输入输出流库中那个独一无二的cout吗?),我们可以在class的私有域中添加一个static类型的计数器,它的初值置为0,然后再对makeAnObject()做点手脚:每次调用它时先检查计数器的值是否已经达到对象个数的上限值,如果是则产生错误,否则才new出新的对象,同时将计数器的值增1.最后,为了避免值复制时产生新的对象副本,除了将构造函数置为私有外,复制构造函数也要特别声明并置为私有。

C++私有构造函数的更多相关文章

  1. Java私有构造函数不能阻止继承

    下面是一个调用已经私有化的单列的函数的列子. 这里用了静态内部类,关键就是静态内部类可以访问外部类的私有构造函数. 这种算是变种继承吧.前提是可以在原来的单列类里添加代码. class Single ...

  2. C#基础(五)——类中私有构造函数作用

    如果类成员有private修饰符,就不允许在类范围以外访问这个类成员.对类构造函数应用private修饰符时,则禁止外部类创建该类的实例.尽管看上去有些不好理解(既然不能实例化,那么这个类还有什么用处 ...

  3. 私有构造函数(c# .NET)

    如果类成员有private修饰符,就不允许在类范围以外访问这个类成员.对类构造函数应用private修饰符时,则禁止外部类创建该类的实例.尽管看上去有些不好理解(既然不能实例化,那么这个类还有什么用处 ...

  4. C#构造函数、私有构造函数、静态构造函数与构造函数执行顺序

    默认构造函数,如果没有为类指定任何构造函数,编译器会自动为类创建一个无参构造函数,用以初始化类的字段:如果为类编写了构造函数,那么编译器就不会再自动生成无参构造函数了.ps.C#不允许用户为结构定义无 ...

  5. 在Spring的Bean注入中,即使你私有化构造函数,默认他还是会去调用你的私有构造函数去实例化

    在Spring的Bean注入中,即使你私有化构造函数,默认他还是会去调用你的私有构造函数去实例化. 如果我们想保证实例的单一性,就要在定义<bean>时加上factory-method=” ...

  6. c# 静态构造函数与私有构造函数共存

    在使用静态构造函数的时候应该注意几点: 1.静态构造函数既没有访问修饰符,也没有参数.因为是.NET调用的,所以像public和private等修饰符就没有意义了. 2.是在创建第一个类实例或任何静态 ...

  7. ASP.NET私有构造函数作用

    一.私有构造函数的特性 1.一般构造函数不是私有或者保护成员,但构造函数可以使私有成员函数,在一些特殊的场合,会把构造函数定义为私有或者保护成员. 2.私有构造函数是一种特殊的实例构造函数.它通常用在 ...

  8. 编写高质量代码改善C#程序的157个建议——建议105:使用私有构造函数强化单例

    建议105:使用私有构造函数强化单例 单例指一个类型只生成一个实例对象.单例的一个简单实现如下所示: static void Main(string[] args) { Singleton.Insta ...

  9. C++ 私有构造函数的作用

    很多情况下要求当前的程序中只有一个object.例如一个程序只有一个和数据库的连接,只有一个鼠标的object.通常我们都将构造函数的声明置于public区段,假如我们将 其放入private区段中会 ...

随机推荐

  1. jquery href属性和click事件冲突

    a标签的定义如下: <a href="javascript:void(0);">test</a> jquery中的click事件: $("a&qu ...

  2. Hive 7、Hive 的内表、外表、分区

    1.Hive的内表 Hive 的内表,就是正常创建的表,在 http://www.cnblogs.com/raphael5200/p/5208437.html 中已经提到: 2.Hive的外表 创建H ...

  3. J2EE学习路线

    第一部分:  JAVA语言基础知识.包括异常.IO流.多线程.集合类.数据库.(切记基础知识一定要时时刻刻巩固,注意,如果你是想以最快速度学习J2EE,关于Java中的Swing知识点,就只做了解)  ...

  4. Struts2简单例子

    Struts实现注册功能 ControlFilter.java package com.jikexueyuan.filter; import java.io.IOException; import j ...

  5. 【CSS3】横屏引导小动画

    演示地址:http://codepen.io/anon/pen/oXbXdX 主要知识点: @media all and (orientation : landscape) { /* 这是匹配横屏的状 ...

  6. webService返回自定义类型的数据处理

    1.自定义一个Student 数据类型: package com.chnic.webservice; import java.io.Serializable; public class Student ...

  7. bat处理文件

    bat处理文件 作用:可以一次性执行多个命令的文件. 为什么要学bat处理文件? 快速运行一个软件一般都会把软件打包一个jar包,但是jar双击可以运行仅对图形化界面的软件起作用,对于控制台的程序是不 ...

  8. 配置错误--分析器错误消息: 无法识别的属性“targetFramework”。请注意属性名称区分大小写。

    在部署网站的时候,很容易遇到这个一样错误:分析器错误消息: 无法识别的属性“targetFramework”.请注意属性名称区分大小写.  错误如图: 错误原因: 部署网站时,使用的应用程序池版本不对 ...

  9. 02—从Cocos2DX视角看游戏组成

    Cocos2DX引擎按照层次逻辑将游戏元素细分为:导演CCDirector.场景CCScene.图层CCLayer.精灵CCSprite.在上面篇中我们已经知道除导演CCDirector外都继承了CC ...

  10. css3实现各种渐变效果,比较适合做手机触屏版

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...