您的位置:首页 > 编程语言 > C语言/C++

C++构造函数以及引用的小理解

2016-09-05 20:05 309 查看
最近在笔试中遇到了一道有关C++的构造函数的问题。类一直都是比较复杂的,话不多说,上代码

int i = 2;
class BaseCls{
public:
//构造函数的顺序:m_nFir = i++;m_nSec = i++;
BaseCls() : m_nSec(i++), m_nFir(i++){
cout << "BaseCls构造" << endl;
cout << "m_nSec = " << m_nSec << endl;
cout << "m_nFir = " << m_nFir << endl;
}
virtual int getResult(){
cout << "MyCls getResult函数" << endl;
return m_nFir + m_nSec;
}
protected:
int m_nFir;
int m_nSec;
};

class MyCls : public BaseCls{
public:
MyCls() :m_nFor(m_nThd), m_nThd(i++){
cout << "MyCls构造生成" << endl;
cout << "m_Thd = " << m_nThd << endl;
cout << "m_nFor =" << m_nFor << endl;
cout << endl;

m_nThd = i;

cout << "m_nThd = i之后:" << endl;
cout << endl;
cout << "m_Thd = " << m_nThd << endl;
cout << "m_nFor =" << m_nFor << endl;
}

int getResult(){
cout << "MyCls getResult函数" << endl;
cout << "m_nFir = " << m_nFir << endl;
cout << "m_nSec = " << m_nSec << endl;
cout << "m_Thd = " << m_nThd << endl;
cout << "m_nFor =" << m_nFor << endl;
return m_nFir + m_nSec + m_nThd + m_nFor;
}
private:
int m_nThd;
int& m_nFor;
};
int main()
{
BaseCls* instance = NULL;
cout << "instance变量的定义" << endl;
instance = new MyCls();
cout << instance->getResult();
delete instance;

return 0;
}
问:输出结果是?

答案:15;

      那就从main函数开始分析吧。首先BaseCls* instance = NULL; 定义一个指针变量暂未指向哪里。然后初始化instance指向堆中的对象new MyCls(); 这时候就要调用类MyCls的构造函数

1、由于MyCls继承BaseCls,所以先调用了BaseCls 的构造函数:

i = 2;
<pre name="code" class="cpp" style="font-size: 18px;">protected:
int m_nFir;
int m_nSec;



BaseCls() : m_nSec(i++), m_nFir(i++){
}
       那么这个时候m_nFir,m_nSec经过构造函数之后的赋值是多少了呢?

       m_nSec是写在前面的,m_nFir写在后面,我一直的想法,顺序应该是m_nSec = i++(m_nSec = i = 2, i = 3);

m_nFir = i++ (m_nFir = i = 3,i = 4);但是结果分析出来不是这样子的(实际:m_nSec = 3,m_nFir = 2),结果到了过来。(很惭愧,请原谅我基础如此不牢固T_T)

2、再调用MyCls自己的构造函数

private:
int m_nThd;
int& m_nFor;


MyCls() :m_nFor(m_nThd), m_nThd(i++){
m_nThd = i;
}
       父类和子类的数据成员我列出来就是要看出里面的不同,子类MyCls里面的m_nFor是引用类型 int&, 前面我们知道了先对后面参数进行赋值,所以顺序就是,m_nThd = i++(m_nThd = 4, i = 5); m_nFor = m_nThd = 4; 最后 m_nThd  = 5 ; 注意注意,m_nFor是引用类型 (引用相当于另外一个变量的别名,就是两个变量都是指向同一块地址上的一个值,所以m_nFor
和 m_nThd 指向的是同一个值,所以m_nThd 改变则m_nFor 改变, m_nFor 改变 m_nThd 也改变),所以m_nFor = 5;

程序的结果截图:



       最后总结了一下这道题的两个要点,一个是构造函数的赋值顺序,一个是引用。

2017-08-17 更新

《C++ Primer 第五版》:成员的初始化顺序与它们在类定义中出现顺序一致:第一个成员先被初始化,然后第二个。构造函数初始值列表中初始值列表中初始值的前后位置关系不会影响实际的初始化顺序。

所以BaseCls先初始化m_nFir后初始化m_nSec。

如果有人看到了,我哪里说错了,求指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++