构造函数定义为private或者protected的好处

将构造函数,析构函数声明为私有和保护的,那么对象如何创建?已经不能从外部调用构造函数了,但是对象必须被构造,应该如何解决,麻烦大家帮忙说明,关于构造,析构函数声明为私有和保护时的用法??? 提出这个问题,说明你已经对c++有所思考了。

从语法上来讲,一个函数被声明为protected或者private,那么这个函数就不能从“外部”直接被调用了。
对于protected的函数,子类的“内部”的其他函数可以调用之。
而对于private的函数,只能被本类“内部”的其他函数说调用。

语法上就是这么规定的,你肯定也知道的咯。
那么为什么有时候将构造函数或者析构函数声明为protected的或者private的?

通常使用的场景如下:
1。如果你不想让外面的用户直接构造一个类(假设这个类的名字为A)的对象,而希望用户只能构造这个类A的子类,那你就可以将类A的构造函数/析构函数声明为protected,而将类A的子类的构造函数/析构函数声明为public。例如:


代码如下:

class A
{ protected: A(){}
  public: ....
};
calss B : public A
{ public: B(){}
  ....
};

A a; // error
B b; // ok

2. 如果将构造函数/析构函数声明为private,那只能这个类的“内部”的函数才能构造这个类的对象了。这里所说的“内部”不知道你是否能明白,下面举个例子吧。


代码如下:

class A
{
private:
    A(){  }
    ~A(){ }

public:
    void Instance()//类A的内部的一个函数
    {
        A a;
    }
};

上面的代码是能通过编译的。上面代码里的Instance函数就是类A的内部的一个函数。Instance函数体里就构建了一个A的对象。

但是,这个Instance函数还是不能够被外面调用的。为什么呢?

如果要调用Instance函数,必须有一个对象被构造出来。但是构造函数被声明为private的了。外部不能直接构造一个对象出来。
A aObj; // 编译通不过
aObj.Instance();
但是,如果Instance是一个static静态函数的话,就可以不需要通过一个对象,而可以直接被调用。如下:


代码如下:

class A
{
private:
    A():data(10){ cout << "A" << endl; }
    ~A(){ cout << "~A" << endl; }

public:
    static A& Instance()
    {
        static A a;
        return a;
    }

void Print()
    {
        cout << data << endl;
    }

private:
    int data;
};

A& ra = A::Instance();
ra.Print();

上面的代码其实是设计模式singleton模式的一个简单的C++代码实现。

还有一个情况是:通常将拷贝构造函数和operator=(赋值操作符重载)声明成private,但是没有实现体。
这个的目的是禁止一个类的外部用户对这个类的对象进行复制动作。
细节请看《effective C++》里面的条款27。

(0)

相关推荐

  • C++中拷贝构造函数的总结详解

    1.什么是拷贝构造函数: 拷贝构造函数嘛,当然就是拷贝和构造了.(其实很多名字,只要静下心来想一想,就真的是顾名思义呀)拷贝又称复制,因此拷贝构造函数又称复制构造函数.百度百科上是这样说的:拷贝构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化.其唯一的参数(对象的引用)是不可变的(const类型).此函数经常用在函数调用时用户定义类型的值传递及返回. 2.拷贝构造函数的形式 复制代码 代码如下: Class X{public: X(); X(const

  • 成员初始化列表与构造函数体中的区别详细解析

    论坛中回答一个别人问题 C++ Primer中在讲构造函数初始化列表的时候有这么一段话:无论是在构造函数初始化列表中初始化成员,还是在构造函数体中对它们赋值,最终结果是相同的.不同之处在于,使用构造函数初始化列表的版本初始化数据成员,没有定义初始化列表的构造函数版本在构造函数体中对数据成员赋值. 请问这里的初始化数据成员与对数据成员赋值的含义是什么?有什么区别? 我知道在数据成员有默认构造函数时是有不同的,但对其他类型的成员呢?其他类型成员的初始化和赋值有区别吗?================

  • 深入解析C++中的构造函数和析构函数

    构造函数:在类实例化对象时自动执行,对类中的数据进行初始化.构造函数可以从载,可以有多个,但是只能有一个缺省构造函数. 析构函数:在撤销对象占用的内存之前,进行一些操作的函数.析构函数不能被重载,只能有一个. 调用构造函数和析构函数的顺序:先构造的后析构,后构造的先折构.它相当于一个栈,先进后出. 复制代码 代码如下: #include<iostream>#include<string>using namespace std;class Student{ public:  Stud

  • c++基础语法:构造函数初始化列表

    C++为类中提供类成员的初始化列表 类对象的构造 顺序是这样的:1.分配内存,调用构造函数 时,隐式/显示的初始化各数据 成员2.进入构造函数后在构造函数中执行一般计算 使用初始化列表有两个原因: 1.必须这样做:如果我们有一个类成员,它本身是一个类或者是一个结构,而且这个成员它只有一个带参数的构造函数,而没有默认构造函数,这时要对这个类成员进行初始化,就必须调用这个类成员的带参数的构造函数,如果没有初始化列表,那么他将无法完成第一步,就会报错. 复制代码 代码如下: class  ABC  .

  • 构造函数不能声明为虚函数的原因及分析

    1. 从存储空间角度,虚函数对应一个指向vtable虚函数表的指针,这大家都知道,可是这个指向vtable的指针其实是存储在对象的内存空间的.问题出来了,如果构造函数是虚的,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没有,怎么找vtable呢?所以构造函数不能是虚函数. 2. 从使用角度,虚函数主要用于在信息不全的情况下,能使重载的函数得到对应的调用.构造函数本身就是要初始化实例,那使用虚函数也没有实际意义呀.所以构造函数没有必要是虚函数.虚函数的作用在于通过父类的指

  • c++基础语法:构造函数与析构函数

    说实话c++还是以前在学校的时候用过的,从毕业到现在一直用c嵌入式编程,现在重新搬出C++语法 ,如果理解上有错误的地方,还请路过的朋友多指正--- 构造函数用来构造一个对象,主要完成一些初始化工作,如果类中不提供构造函数,编译器会默认的提供一个默认构造函数(参数为空的构造函数就是默认构造函数) :析构函数是隐式调用的,delete对象时候会自动调用完成对象的清理工作. 现在主要看看继承中的构造函数和析构函数的调用: 复制代码 代码如下: class  A {} :class  B : publ

  • 浅析C++中的虚函数

    一.定义定义:在某基类中声明为 virtual 并在一个或多个派生类中被重新定义的成员函数. 语法:virtual 函数返回类型函数名(参数表) { 函数体 } 用途:实现多态性,通过指向派生类的基类指针,访问派生类中同名覆盖成员函数 虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public. 定义为virtual的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数. 二.作用虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函

  • c++ 虚函数与纯虚函数的区别(深入分析)

    在面向对象的C++语言中,虚函数(virtual function)是一个非常重要的概念.因为它充分体现 了面向对象思想中的继承和多态性这两大特性,在C++语言里应用极广.比如在微软的MFC类库中,你会发现很多函数都有virtual关键字,也就是说, 它们都是虚函数.难怪有人甚至称虚函数是C++语言的精髓. 那么,什么是虚函数呢,我们先来看看微软的解释: 虚函数是指一个类中你希望重载的成员函数,当你用一个基类指针或引用指向一个继承类对象的时候,你调用一个虚函数,实际调用的是继承类的版本. 这个定

  • 深入解析C++中的虚函数与多态

    1.C++中的虚函数C++中的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数.这种技术可以让父类的指针有"多种形态",这是一种泛型技术.所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法.比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议. 对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Tab

  • C++拷贝构造函数(深拷贝与浅拷贝)详解

    对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面看一个类对象拷贝的简单例子. 复制代码 代码如下: #include <iostream>using namespace std; class CExample {private:    int a;public:    CExample(int b)    { a=b;}    void Show ()    {       

随机推荐