C++构造函数以及引用的小理解
2016-09-05 20:05
309 查看
最近在笔试中遇到了一道有关C++的构造函数的问题。类一直都是比较复杂的,话不多说,上代码
答案:15;
那就从main函数开始分析吧。首先BaseCls* instance = NULL; 定义一个指针变量暂未指向哪里。然后初始化instance指向堆中的对象new MyCls(); 这时候就要调用类MyCls的构造函数
1、由于MyCls继承BaseCls,所以先调用了BaseCls 的构造函数:
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自己的构造函数
和 m_nThd 指向的是同一个值,所以m_nThd 改变则m_nFor 改变, m_nFor 改变 m_nThd 也改变),所以m_nFor = 5;
程序的结果截图:
![](https://img-blog.csdn.net/20160905200344989?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
最后总结了一下这道题的两个要点,一个是构造函数的赋值顺序,一个是引用。
2017-08-17 更新
《C++ Primer 第五版》:成员的初始化顺序与它们在类定义中出现顺序一致:第一个成员先被初始化,然后第二个。构造函数初始值列表中初始值列表中初始值的前后位置关系不会影响实际的初始化顺序。
所以BaseCls先初始化m_nFir后初始化m_nSec。
如果有人看到了,我哪里说错了,求指正。
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++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C++的template模板中class与typename关键字的区别分析
- C与C++之间相互调用实例方法讲解