博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[C++基础]在构造函数内部调用构造函数
阅读量:5838 次
发布时间:2019-06-18

本文共 1572 字,大约阅读时间需要 5 分钟。

看下面的面试题:

#include 
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; return 0; }

  打印的结果是系统的一个随机值。所以这种直接在构造函数中调用另外的一个构造函数是不可行的。

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

我们知道,当定义一个对象时,会按顺序做2件事情:
1)分配好内存(非静态数据成员是未初始化的)
2)调用构造函数(构造函数的本意就是初始化非静态数据成员)
显然上面代码中,CLS obj;这里已经为obj分配了内存,然后调用默认构造函数,但是默认构造函数还未执行完,却调用了另一个构造函数,这样相当于产生了一个匿名的临时CLS对象,它调用CLS(int)构造函数,将这个匿名临时对象自己的数据成员m_i初始化为0;但是obj的数据成员并没有得到初始化。于是obj的m_i是未初始化的,因此其值也是不确定的。

提示:C++实例化对象的方式很多,特别是在栈中实例化对象,看下面的例子:CLS obj;	在栈中实例化一个对象,调用默认构造函数CLS obj(10);	在栈中实例化一个对象,调用int参数的构造函数CLS obj();	这不是实例化对象,这是声明一个返回类型为CLS,参数为void的函数。当然这个函数声明可以在其他的函数内部CLS(10);	调用int参数的构造函数在栈中产生一个匿名的对象,类似new CLS(10);也是产生匿名的对象,只不过new时要有一个指针接收这个匿名对象CLS();	同上,只不过这里调用无参构造函数  

从这里,我们归纳如下:

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

这里可以看到,new也可以操作栈上已经分配好的内存。另: 若构造函数调用自身,则会出现无限递归调用,是不允许的。

所以,在实际使用的时候,单纯的在构造函数中调用其它的构造函数,只是会产生一个临时的匿名变量。如果仅仅是为了重用代码,可以把重用的代码封装成一个新的函数。

 

转载于:https://www.cnblogs.com/stemon/p/4834043.html

你可能感兴趣的文章
JS学习随笔记录1
查看>>
Linux的inode的理解
查看>>
构建大型企业网络-三层交换与VTP协议
查看>>
神啊,6小时30分钟,完成想要的所有Lync测试
查看>>
禁用php函数的设置
查看>>
IOS项目实战-登录解析
查看>>
假期为是否辞职做好数据参考
查看>>
启用ESXi的SSH服务
查看>>
总是弹出visual studio 实时调试器 三种解决办法
查看>>
Java程序员从笨鸟到菜鸟之(九十二)深入java虚拟机(一)——java虚拟机底层结构详解...
查看>>
SpringMVC POST和GET问题
查看>>
perl:warning:Setting locale failed解决办法
查看>>
git学习笔记
查看>>
php中类的继承
查看>>
Tomcat在Linux上的安装与配置--1
查看>>
网银互联获杭州市云计算协会理事单位授牌
查看>>
perl 将XML格式转换为html、txt、pod格式
查看>>
sed基础篇
查看>>
搭建 Apache RocketMQ 单机环境
查看>>
第一章 实体框架入门
查看>>