#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);}
};

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

转自:

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

转载于:https://www.cnblogs.com/zzdbullet/p/10475798.html

C++中构造函数调用构造函数相关推荐

  1. 从一道题谈C++中构造函数调用构造函数

    转载:http://www.cnblogs.com/chio/archive/2007/10/20/931043.html 题目如下:问下列代码的打印结果为0吗? #include <stdli ...

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

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

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

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

  4. 构造函数调用默认构造函数_显式无参数构造函数与默认构造函数

    构造函数调用默认构造函数 大多数不熟悉Java的开发人员都会Swift了解到,如果他们没有指定至少一个显式构造函数,则会为Java类隐式创建一个" 默认构造函数 "( 由javac ...

  5. c/c++教程 - 2.4.2.3~4 拷贝构造函数的调用时机,构造函数调用规则

    目录 4.2.3 拷贝构造函数的调用时机 4.2.4 构造函数调用规则 相关教程 4.2.3 拷贝构造函数的调用时机 C++中拷贝构造函数调用时机,通常有三种情况: 使用一个已经创建完毕的对象来初始化 ...

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

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

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

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

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

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

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

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

最新文章

  1. mongodb重命名集合、数据库
  2. 【阿圆实验】Consul HA 高可用方案
  3. php静态页面缓存,php处理静态页面:页面设置缓存时间实例
  4. 数据加解密和数据签名验签
  5. php-frm进程管理,PHP内核探索-进程管理
  6. iPhone 12s渲染图曝光,刘海变小了!
  7. 60-130-336-源码-source-kafka相关-Flink读取kafka
  8. Python web —— webbrowser + feedparser 网络爬虫刷博器
  9. struts2 tutor
  10. Obj-C 实现设计模式 -- Adapter
  11. Rust语言教程(6) - 错误处理和可选值
  12. 根据经纬度实现附近的人
  13. 算术运算符——加号的多种和自增自减
  14. Java面试_非技术问答
  15. 三星s8文档有html,三星s8有哪些特殊功能 这些绝对能让你羡慕
  16. CCF TALKs 报名 | 今天,技术如何推动社会进步
  17. vue 如何实现点击动态更新图形验证码
  18. 帮你快速拿Offer!Android攒了一个月的面试题及解答,含BATJM大厂
  19. Opencv复习笔记
  20. ubuntu操音量调整命令amixer

热门文章

  1. 不仅是 64 位 Android L 还有这 9 大亮点
  2. 交换机多生成树协议MSTP
  3. java 线程关闭小结(转)
  4. 一款由css3和jquery实现的响应式设计导航
  5. Linux-6.5下 MariaDB-10基于percona-XtraBackup备份工具的原理及配置详解
  6. tomcat 初始管理用户和密码
  7. linux挂载其他硬盘
  8. scala 提交任务
  9. 远程usb端口映射_PLC远程控制
  10. winform模拟登陆网页_【教程】模拟登陆网站 之 C#版(内含两种版本的完整的可运行的代码)...