今天在读《C++Primer》时读到委托构造函数一节,书中关于委托构造函数是这样描述的:

一个委托构造函数使用它所属的类的其他构造函数执行自己的初始化过程,或者说它把自己的一些(或者全部)职责委托给了其他构造函数。和其他构造函数一样,一个委托构造函数也有一个成员初始值的列表和一个函数体。在委托构造函数内,成员的初始值列表只有一个唯一的入口,就是类名本身。和其他成员初始值一样,类名后面紧跟圆括号括起来的参数列表,参数列表必须与类中另外一个构造函数匹配。

  初读这段话,可能理解上有一些偏差,一开始觉得意思就是一个构造函数可以用其他构造函数。于是写了段测试代码:

class A
    {
        private:
            int a;
            char c;
        public:
            A(int num):a(num){}
            A(char C):c(C){}
            A(int num,char C):A(num),A(C){}//调用其他两个构造函数
    };

示例化一个对象x:A x(0,'x')
编译不过,提示错误:

error:mem-initializer for ‘class A’ follows constructor delegation A(int num,char C):A(num),A(C){}

成员初始化失败!StackOverFlow上也有人遇到了这个问题,有人给出了解答:

When you delegate the member initialization to another constructor, there is an assumption that the other constructor initializes the object completely, including all members. You can’t therefore initialize any of the members again.

 意思大概是当你委托另一个构造函数时,假定这个构造函数可以完整地构造出这个对象。上面的无论是A(int num)还是A(char C)都不能完整地构造出对象。按照这个思路,改一下代码如下:

class A
    {
        private:
            int a;
            char c;
        public:
            A(int num,char C):a(num),c(C){}
            A(int num):A(num,' '){}//给char c默认值
    };

 这下代码可以编译通过了。那么是否真的这样呢?再用一段测试代码:

class A
    {
        private:
            int a;
            int b;
            char c;
            //char d;
        public:
            A(int num0,int num1,char C):a(num0),b(num1),c(C){}
            A(int num0,char C):A(num0,0,C){}//委托上一个构造函数
            A(int num0):A(num0,' '){}       //委托上一个构造函数 
    };

  代码编译通过,注意到这里第二个构造函数委托第一个构造函数,能完整地构造出对象;而第三个构造函数委托第二个函数,也能完整地构造出对象。如果第一个构造函数不能完整地构造出对象,结果是什么样呢?把上面对char d的注释去掉,发现代码也能编译通过,d有默认值空!!!
那么StackOverFollow上的解答就是有误的,被委托的构造函数并不用包含所有成员变量,只要包含最大数量的成员变量即可。关于stackoverflow上的解答请点这里。
不过,我发现答主后面补充了一下:

As a general rule, you should fully specify that version of the constructor that takes the largest number of arguments, and then delegate from the other versions (using the desired default values as arguments in the delegation).

  普遍规则是被委托的构造函数应该包含最大数量的参数,然后被其他构造函数委托(可以使用默认值进行委托构造)~
  了解到在使用委托构造函数时,不能再进行成员列表初始化,而只能在函数体内进行初始化其他成员变量。那么我们在委托其他构造函数构造对象时,一些成员变量以默认值构造了,在函数体内进行初始化就不叫初始化了,只能叫重新赋值了。见下面例子:

class A
  {
      private:
          int a;
          int b;
          char c;
          char d;
      public:
          A(int num0,int num1,char C):a(num0),b(num1),c(C){}
          A(int num0,char C):A(num0,0,C){}//b默认初始化为0
          A(int num0):A(num0,'p'){b=1;}//b重新赋值为1
          void getMembers()
          {
              cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;
          }
  };

在委托第二个构造函数构造时,b被初始化为0,这里我们在函数体内重新赋值为1,那么b到底是0还是1呢?结果是1。函数体内的初始化要晚于成员列表初始化,即委托其他构造函数构造完后,在进行函数体内的赋值。

总结
  一个构造函数想要委托另一个构造函数,那么被委托的构造函数应该包含较大数量的参数,初始化较多的成员变量。而且在委托其他构造函数后,不能再进行成员列表初始化,而只能在函数体内进行初始化其他成员变量。
————————————————
版权声明:本文为CSDN博主「赤道以北」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/huangtiao2509/article/details/73882305

C++构造函数之委托构造函数相关推荐

  1. 委托构造函数继承构造函数

    委托构造函数 委托构造函数的引入 小明和李华给外国友人写信从高中写到了考研写累了,突然想唱歌,为了方便这哥俩唱歌,咱写了个唱歌类给他们.这哥俩唱的不好,就限制他俩只能唱三句.因为有1~3句的选择,就写 ...

  2. C++进阶教程 - 委托构造函数和继承构造函数

    委托构造函数 什么是委托构造函数? 委托构造函数是由C++11引入的新概念,是对C++构造函数的改进,允许构造函数使用初始化列表调用同类中的其他构造函数,旨在简化构造函数的书写,提升代码的可维护性,降 ...

  3. C++11:委托构造函数

    前言 如果一个类中重载了多个构造函数,并且在每个构造函数中都需要对某些变量进行初始化,这时候就会出现很多重复的代码,在C++11之前存在这个问题.而C++11中新增的委托构造函数,就是为了解决这个问题 ...

  4. [C++11]委托构造函数

    委托构造函数允许使用同一个类中的一个构造函数调用其他的构造函数,从而简化相关变量的初始化. 注意点: 1.这种链式的构造函数调用不能形成一个闭环(死循环),否则会在运行期抛异常. 2.如果要进行多层构 ...

  5. C++11 委托构造函数

    1.简介 委托构造函数(Delegating Constructor)由 C++11 引入,是对 C++ 构造函数的改进,允许构造函数通过初始化列表调用同一个类的其他构造函数,目的是简化构造函数的书写 ...

  6. 【Kotlin】Kotlin 类的继承 一 ( 类继承基本方式 | final 关键字 | 子类主构造函数 | 子类次构造函数 )

    文章目录 I . 类继承基本方式 II . 使用 final 禁止类继承 / 方法重写 III . 父类没有主构造函数 IV . 父类有主构造函数 V . 父类构造函数与子类构造函数总结 I . 类继 ...

  7. Kotlin 主构造函数与次构造函数的理解

    遇到了Kotlin: Primary constructor call expected的报错 如果类有一个主构造函数,每个次构造函数需要委托给主构造函数, 可以直接委托或者通过别的次构造函数间接委托 ...

  8. C++ 复制构造函数或者拷贝构造函数

    复制构造函数 是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象. 复制构造函数通常用于: 通过使用另一个同类型的对象来初始化新创建的对象. 复制对象把它作为参数传 ...

  9. 不存在从void转换到sqlist的适当构造函数_拷贝构造函数与赋值构造函数

    拷贝构造函数与赋值构造函数 在C++中,如果要创建一个新的类,并用已有的类来给它附初值.就要用到拷贝构造函数,拷贝构造函数又分为两种. 1.合成的拷贝构造函数 在你没有定义自己的拷贝构造函数而又调用了 ...

最新文章

  1. 大数据架构和模式(一)——大数据分类和架构简介
  2. git 设置 key 到服务器,同步代码不需要输入用户名和密码
  3. Java减少依赖_去掉JAVA部分依赖的事例
  4. vue 3.0和2.0区别_一文看懂 Vue.js 3.0 的优化
  5. 从零开始学前端:jQuery官网 --- 今天你学习了吗?(CSS:Day26)
  6. 基于公司云平台的素材归档系统(一)
  7. 企业服务总线(EnterpriseServiceBus,ESB)
  8. 计算机电缆一般用在哪里,计算机电缆的型号有哪些,它们的用途是什么
  9. 两台笔记本一台连接不上wifi
  10. Rest Stops 题解
  11. python中random.seed(1)_Python-random.seed()
  12. 基于java的药店管理系统
  13. linux查找命令which、whereis、find比较解析
  14. 人像分割技术解析与应用
  15. Fire Net 放碉堡 —— DFS
  16. 如何在右下角显示服务器图标,win7通知区域图标、电脑右下角图标显示和隐藏如何设置?...
  17. 51nod_2929 部落战争(DAG最小路径覆盖)
  18. MindMaster---总结案例
  19. 面向对象改造——50道100以内的加减法口算习题
  20. php案例:解压多个压缩包

热门文章

  1. apache下php无法连接mysql问题的解决
  2. (Head First 设计模式)学习笔记(1)
  3. java线程在什么时候结束,java – 什么时候线程超出范围?
  4. [Python图像识别] 四十八.Pytorch构建Faster-RCNN模型实现小麦目标检测
  5. Java+MyEclipse+Tomcat (三)配置MySQL及查询数据显示在JSP网页中
  6. 【数据结构与算法】之深入解析“路径交叉”的求解思路与算法示例
  7. 【数据结构与算法】之组成和的完全平方数最少个数的求解思路与算法示例
  8. LeetCode Shell 192. 统计词频
  9. 大量小文件存储提高效率要点详解
  10. Hex与float之间相互转换