转载:http://www.cnblogs.com/chio/archive/2007/10/20/931043.html

题目如下:问下列代码的打印结果为0吗?

#include <stdlib.h>
#include <iostream>
using namespace std;

struct CLS
{
    int m_i;
    CLS( int i ) : m_i(i){}
    CLS()
    {
        CLS(0);
    }
};
int main()
{
    CLS obj;
    cout << obj.m_i << endl;

system("PAUSE");
    return 0;
}

打印结果是不定的,不一定为0

代码奇怪的地方在于构造函数中调用了自己的另一个构造函数

我们知道,当定义一个对象时,会按顺序做2件事情:
1)分配好内存(非静态数据成员是未初始化的)
2)调用构造函数(构造函数的本意就是初始化非静态数据成员)

显然上面代码中,CLS obj;这里已经为obj分配了内存,然后调用默认构造函数,但是默认构造函数还未执行完,却调用了另一个构造函数,这样相当于产生了一个匿名的临时CLS对象,它调用CLS(int)构造函数,将这个匿名临时对象自己的数据成员m_i初始化为0;但是obj的数据成员并没有得到初始化。于是obj的m_i是未初始化的,因此其值也是不确定的

从这里,我们归纳如下:
1)在c++里,由于构造函数允许有默认参数,使得这种构造函数调用构造函数来重用代码的需求大为减少
2)如果仅仅为了一个构造函数重用另一个构造函数的代码,那么完全可以把构造函数中的公共部分抽取出来定义一个成员函数(推荐为private),然后在每个需要这个代码的构造函数中调用该函数即可
3)偶尔我们还是希望在类的构造函数里调用另一个构造函数,可以按下面方式做:
在构造函数里调用另一个构造函数的关键是让第二个构造函数在第一次分配好的内存上执行,而不是分配新的内存,这个可以用标准库的placement new做到:

先看看标准库中placement new的定义

inline void *__cdecl operator new(size_t, void *_P)
{
    return (_P); 

可见没有分配新的内存。

正确的方式:

struct CLS
{
    int m_i;
    CLS( int i ) : m_i(i){}
    CLS()
    {
        new (this)CLS(0);
    }
};

另外的方法: this->CLS::CLS(0)

另: 若构造函数调用自身,则会出现无限递归调用,是不允许的

从一道题谈C++中构造函数调用构造函数相关推荐

  1. C++中构造函数调用构造函数

    #include <stdlib.h> #include <iostream> using namespace std;struct CLS {int m_i;CLS( int ...

  2. 菱形继承中构造函数调用问题

    菱形继承中构造函数调用问题 在某一个虚基类的任何一个派生类的构造函数中,都要将该虚基类的构造函数显示列出来. 包含虚基类的派生类对象的构造函数的调用顺序如下: 虚基类的构造函数在非虚基类之前调用. 若 ...

  3. java构造函数调用构造函数

    一个类可包含多个构造函数,在java中一个构造函数可以调用另一个构造函数来实现自身. 调用其他构造函数可以使用this关键字进行调用. 例如下面代码: public class Student {pr ...

  4. 继承构造函数调用顺序_C ++中带有继承的构造函数调用的顺序

    继承构造函数调用顺序 Base class constructors are always called in the derived class constructors. Whenever you ...

  5. 浅谈javascript中原型(prototype)、构造函数、对象实例及三者之间的关系

    转自:http://www.cnblogs.com/zhangwei412827/archive/2012/12/14/2816263.html 浅谈javascript中原型(prototype). ...

  6. oracle hash join outer,CSS_浅谈Oracle中的三种Join方法,基本概念 Nested loop join: Outer - phpStudy...

    浅谈Oracle中的三种Join方法 基本概念 Nested loop join: Outer table中的每一行与inner table中的相应记录join,类似一个嵌套的循环. Sort mer ...

  7. 类和对象—对象特性—构造函数调用规则

    默认情况下,C++编译器至少给一个类添加三个函数 默认构造函数(无参,函数体为空) 默认析构函数(无参,函数体为空) 默认拷贝构造函数,对属性进行值拷贝 构造函数调用规则如下: 如果用户定义有参构造函 ...

  8. 类和对象—对象特性—拷贝构造函数调用时期

    C++中拷贝构造函数通常有三种情况 使用一个已经建立完毕的对象来初始化一个新对象 值传递的方式给函数参数传值 以值方式返回局部对象 #include <iostream> using na ...

  9. 《从零开始学Swift》学习笔记(Day 42)——构造函数调用规则

    原创文章,欢迎转载.转载请注明:关东升的博客 在构造函数中可以使用构造函数代理帮助完成部分构造工作.类构造函数代理分为横向代理和向上代理,横向代理只能在发生在同一类内部,这种构造函数称为便利构造函数. ...

最新文章

  1. java垃圾回收根对象_Java垃圾回收怎么理解?
  2. (原創) 我有牙周病了 (日記)
  3. Android开发之添加QQ群的方法(官方代码)
  4. Centos7.5常用firewall-cmd命令集
  5. hive jdbc 访问 配置_Hive入门级教程(详细)
  6. React redux
  7. 【python教程入门学习】值得学习练手的70个Python项目(附代码)
  8. cAdvisor资源监控工具入门
  9. fqa什么意思_FQA是啥意思
  10. 优秀工程师必备的三大思维
  11. 研究人员发现英特尔芯片组中可能被黑客使用的“新功能”VISA
  12. 重装系统是否影响计算机,电脑重装系统会对电脑造成伤害吗? 答案说出来你可能都不信...
  13. 20211高考成绩查询,青岛理工大学教务系统URP成绩查询、网上选课查分 http://211.64.192.21/,精英高考网...
  14. 特奢汇:以智慧新零售 引领行业革新
  15. 手把手教你写《雷神》游戏(四)
  16. 亚马逊的核心运营规律(我是做了3年亚马逊的)
  17. 密歇根安娜堡大学的计算机科学教授,密歇根大学安娜堡分校计算机科学与工程研究生offer及申请要求...
  18. ARM-9 4412板、linux-3.14内核、usb转串口pl2303驱动的移植相关问题
  19. win10win11win7打印机连接共享错误0x00709打印失败错误修复工具
  20. Spring循环依赖问题,Spring是如何解决循环依赖的?

热门文章

  1. kali怎么成为管理员_关于物业经理证怎么考
  2. P3243 [HNOI2015]菜肴制作 (拓扑排序)
  3. 米联客udp_stack以太网协议栈使用教程
  4. debian虚拟机调分辨率
  5. 好消息!心理治疗纳入医保再添一省份
  6. Web基础和HTTTP协议
  7. imagebutton的鼠标悬停事件:鼠标指向时显示图片1,鼠标离开时显示图片2
  8. 「DaoCloud 道客」与中国通服达成战略合作,共建工业互联网共生生态
  9. Light Field 光场
  10. 2019-12 试卷中的生词(04)