C++ 成员类 (类里面包含另一类的对象) 构造函数调用问题

happy08god 2014-02-07 10:20:42
各位高手,本菜鸟在阅读他人代码的时候,遇到了一个“成员类”
(类里面包含另一个类的对象) 的构造函数调用问题,具体问题如下:


#include <iostream>
using namespace std;

class A {

public:

int mInt;

A()
{
cout << " in A Default Constructor : mInt = " << mInt << endl;
mInt = 0;
}

void setIntVal(int mSet)
{
cout << " in setIntVal : mInt = " << mInt << " mSet = " << mSet << endl;
if(mInt < mSet)
{
mInt = mSet;
}
}

};

class B {

private:
int b;
A aObj;
public:
B()
{
cout << " in B Default Constructor" << endl;
b = 10;
aObj.setIntVal(20);
}

};

int main() {
// your code goes here

B * pB = new B();

delete pB;

return 0;
}


问题: A中的构造函数会被调用么? 为什么?


程序运行结果:

in A Default Constructor : mInt = 0
in B Default Constructor
in setIntVal : mInt = 0 mSet = 20



本人属C++菜鸟一枚,以前是搞C的。自己写C++的时候,如果需要调用
A类的构造函数,会通过在B类的构造函数那里去“显示调用”,比如通过
构造函数的初始化列表,或者去new一个A类的对象。但对于这种“隐式”的
处理,小弟就看不懂了。

弱问下: 这个运行结果,与A类定义,实现的无参构造函数也有关吧? 要是
换成有参数的就不行了吧? 这种无参数的构造函数,是这种情况下默认
调用的构造函数吗?

如果方便,还请高手释疑后顺便给个相关知识点的参考链接,小弟再参考参考。

求各位大大指点了,万分感谢!!!
...全文
3147 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
SmallCoder1992 2014-02-08
  • 打赏
  • 举报
回复
引用 5 楼 axqscz 的回复:
A() { cout << " in A Default Constructor : mInt = " << mInt << endl; mInt = 0; } 这里很纳闷为什么先输出后赋值的情况下mInt还是会等于0?不应该是乱码吗?
这个我觉得没错啊!因为mInt在静态时候就已经完成了赋值,你在建立new B()时候应该就已经完成赋值了,这是我的理解
堂风 2014-02-08
  • 打赏
  • 举报
回复
main->需要创建一个B*的变量->找到B类->需要一个int成员->需要一个A类成员->找到A类->需要一个int成员->构造A类->打印->给mInt赋值(赋值在后为什么执行的时候就已经是0了,感到迷惑)->构造A类完成实例化B类中的aObj->执行B类的构造函数->输出->赋值->调用aObj成员的setIntVal(int)方法->构造B完成->在main()中完成了pB的实例化。以前有人跟我说过构造函数就是需要确定一个类在内存中所占用的长度,试问当你创建一个类的时候不知道给他分配多大空间又怎么继续进行呢? 不足之处还请批评指正。
MichelleKdf 2014-02-08
  • 打赏
  • 举报
回复
in A Default Constructor : mInt = 0 这个地方,我想是楼主写错了吧。。。。。 要不然就是太巧合了
码混一个 2014-02-08
  • 打赏
  • 举报
回复
我发现从我开始问了个很2的问题之后大家都晕了,看来基本功很总要啊!
码混一个 2014-02-08
  • 打赏
  • 举报
回复
引用 13 楼 happy08god 的回复:
[quote=引用 5 楼 axqscz 的回复:] A() { cout << " in A Default Constructor : mInt = " << mInt << endl; mInt = 0; } 这里很纳闷为什么先输出后赋值的情况下mInt还是会等于0?不应该是乱码吗?
这个。。。本来应该是个随机值的,但我用的编译器就是给出了这样的结果。。。[/quote] 看来你的运气是相当的牛B
happy08god 2014-02-08
  • 打赏
  • 举报
回复
引用 9 楼 ss_bornli 的回复:
请阅读C++ primer 第十一章 十二章,你想知道的,里面都有;我这有电子版,想要的话可以给你
谢谢,已经在《 12.4.3 默认构造函数》 章节找到答案: 具有类类型的成员通过运行各自的默认构造函数来进行初始化。
happy08god 2014-02-08
  • 打赏
  • 举报
回复
引用 5 楼 axqscz 的回复:
A() { cout << " in A Default Constructor : mInt = " << mInt << endl; mInt = 0; } 这里很纳闷为什么先输出后赋值的情况下mInt还是会等于0?不应该是乱码吗?
这个。。。本来应该是个随机值的,但我用的编译器就是给出了这样的结果。。。
happy08god 2014-02-08
  • 打赏
  • 举报
回复
引用 3 楼 taodm 的回复:
楼主,想在C++的路上走远一点,自己认认真真啃下一本合格的教材是最低要求的。 不要想偷懒啊。
谢谢,有点C++基础,但以前没这么用过,都是自己写的显示调用构造函数的。
SmallCoder1992 2014-02-08
  • 打赏
  • 举报
回复
引用 10 楼 shenzhimingdashen 的回复:
[quote=引用 8 楼 u010222864 的回复:] [quote=引用 5 楼 axqscz 的回复:] A() { cout << " in A Default Constructor : mInt = " << mInt << endl; mInt = 0; } 这里很纳闷为什么先输出后赋值的情况下mInt还是会等于0?不应该是乱码吗?
这个我觉得没错啊!因为mInt在静态时候就已经完成了赋值,你在建立new B()时候应该就已经完成赋值了,这是我的理解[/quote] 我vs2010实测结果是:
 in A Default Constructor :  mInt = -842150451
 in B Default Constructor
 in setIntVal : mInt = 0 mSet = 20
Press any key to continue . . .
new B()时候怎么会先去给A的成员赋值? 楼主肯定哪里搞错了吧?[/quote] 的确是我理解错了一个地方,我没注意构造函数,是我的错误,不好意思
Jim_sh 2014-02-08
  • 打赏
  • 举报
回复
引用 8 楼 u010222864 的回复:
[quote=引用 5 楼 axqscz 的回复:] A() { cout << " in A Default Constructor : mInt = " << mInt << endl; mInt = 0; } 这里很纳闷为什么先输出后赋值的情况下mInt还是会等于0?不应该是乱码吗?
这个我觉得没错啊!因为mInt在静态时候就已经完成了赋值,你在建立new B()时候应该就已经完成赋值了,这是我的理解[/quote] 我vs2010实测结果是:
 in A Default Constructor :  mInt = -842150451
 in B Default Constructor
 in setIntVal : mInt = 0 mSet = 20
Press any key to continue . . .
new B()时候怎么会先去给A的成员赋值? 楼主肯定哪里搞错了吧?
码混一个 2014-02-08
  • 打赏
  • 举报
回复
A() { cout << " in A Default Constructor : mInt = " << mInt << endl; mInt = 0; } 这里很纳闷为什么先输出后赋值的情况下mInt还是会等于0?不应该是乱码吗?
道希 2014-02-08
  • 打赏
  • 举报
回复
请阅读C++ primer 第十一章 十二章,你想知道的,里面都有;我这有电子版,想要的话可以给你
Pump天天学习 2014-02-07
  • 打赏
  • 举报
回复
1.这个运行结果,与A类定义,实现的无参构造函数也有关吧? 肯定有关,因为B中包含A,所以在构造B时会先构造A

   B()//B的构造函数,虽然没有显示调用A的ctor,但是相当于在初始化列表中有个aObj()
    {
        cout << " in B Default Constructor" << endl;
        b = 10;
        aObj.setIntVal(20);
    }
2.要是换成有参数的就不行了吧? 这要看A中是否提供了默认构造函数, 如果A没有提供默认构造函数,并且用户声明了一个带参数的构造函数,那么编译器不会合成出一个默认的出来,所以在B的初始化列表中需要显示提供构造A所需的参数。 相反,如果A的众多构造函数里有一个默认构造函数,那么B的构造函数中就算没有显示调用A的,编译器也会帮我们调用
taodm 2014-02-07
  • 打赏
  • 举报
回复
楼主,想在C++的路上走远一点,自己认认真真啃下一本合格的教材是最低要求的。 不要想偷懒啊。
zhuyf87 2014-02-07
  • 打赏
  • 举报
回复
class B有一个member: A aObj; 那构造B对象时,肯定会先构造A对象,就肯定会调用A的构造函数。
unituniverse2 2014-02-07
  • 打赏
  • 举报
回复
只要有“创建”(非专业的叫法)对象的过程,对象类的构造函数的调用不可避免(除非类的作者没有显式提供
任何
构造函数) B类构造函数中不写对aObj的构造,相当于其实写了": aObj()"。就算你故意不懈B类的构造函数,就是因为aObj有个自定义的构造函数而会导致编译器暗中给你生成一个B()并且用其调用aObj()

64,651

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧