菜鸟请教C++构造函数调用顺序的问题????

hxq_dms 2007-03-14 12:24:06
我看到书上的程序是这样的,可是觉得它构造函数的调用顺序和我理解的不一样,想请教一下大家
#include <iostream>
using namecpace std;
class B1 //基类B1声明
{ public:
B1(int i) {cout<<"constructing B1 "<<i<<endl;}
~B1() {cout<<"destructing B1 "<<endl;}
};
class B2 //基类B2声明
{public:
B2(int j) {cout<<"constructing B2 "<<j<<endl;}
~B2() {cout<<"destructing B2 "<<endl;}
};
class B3 //基类B3声明
{public:
B3(){cout<<"constructing B3 *"<<endl;}
~B3() {cout<<"destructing B3 "<<endl;}
};
class C: public B2, public B1, public B3
{public:
C(int a, int b, int c, int d):
B1(a),memberB2(d),memberB1(c),B2(b){}
private:
B1 memberB1;
B2 memberB2;
B3 memberB3;
};
int main()
{ C obj(1,2,3,4); }

请教为什么这里
C(int a, int b, int c, int d):
B1(a),memberB2(d),memberB1(c),B2(b){ }
是这个顺序

...全文
371 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
tengerye 2010-11-05
  • 打赏
  • 举报
回复
派生类的构造函数的参数列表必须调用基类的构造函数,那为什么不可以在派生类的构造函数里显示调用呢?如:
class A
{
private:
int a;
public:
A(int pa = 0):a = pa
{
a = pa
}
};

class B:public A
{
private:
int b
public:
B(int pa,int pb):b = pb
{
A(pa);
}
};


void main()
{
B(1,1);
}
调试的时候发现a = 0,b = 1为什么?
todototry 2007-03-14
  • 打赏
  • 举报
回复
先基类的后派生类的,层层进行, ^_^
DonaldKnuth 2007-03-14
  • 打赏
  • 举报
回复
构造函数初始化列表的中的初始化顺序与初始化列表中的排列顺序无关,它是与
被初始化的成员在类中定义的先后顺序进行初始化的。
hxq_dms 2007-03-14
  • 打赏
  • 举报
回复
谢谢,我想明白了。呵呵,其实就是它自己这样赋值的,我自己变傻了。
hxq_dms 2007-03-14
  • 打赏
  • 举报
回复
to 克努特
那为什么结果不是
constructing B2 1
constructing B1 2
constructing B3 *
constructing B1 3
constructing B2 4
constructing B3 *
呢?我是说形参赋值的顺序为什么回是2,1,3,4呢
DonaldKnuth 2007-03-14
  • 打赏
  • 举报
回复
to hxq_dms(小司)
是的,基类构造函数被继承时的声明顺序是B2,B1,B3啊!
hxq_dms 2007-03-14
  • 打赏
  • 举报
回复
执行结果是
constructing B2 2
constructing B1 1
constructing B3 *
constructing B1 3
constructing B2 4
constructing B3 *

为什么参数被赋值的顺序是2 1 3 4啊?
hxq_dms 2007-03-14
  • 打赏
  • 举报
回复
我还是不明白。
1. 调用基类构造函数,调用顺序按照它们被继承时声明的顺序(从左向右)。
2. 调用成员对象的构造函数,调用顺序按照它们在类中声明的顺序。
3. 派生类的构造函数体中的内容。

首先,我不明白
C(int a, int b, int c, int d):
B1(a),memberB2(d),memberB1(c),B2(b){} 为什么有四个形参?
其次,基类构造函数被继承时的声明顺序难道不是B2,B1,B3吗?
DonaldKnuth 2007-03-14
  • 打赏
  • 举报
回复
同时,c++标准并未规定, 对于不同类范围模快中的成员的初始化顺序,如一个public块中的
成员与另一个public块中成员同时初始时的顺序,但是一般的编译器都以各个块在类中出现的
先后顺序为准。
DonaldKnuth 2007-03-14
  • 打赏
  • 举报
回复
to hxq_dms(小司)
是这样的,在初始化列表中的顺序无论是什么,执行的顺序都是先调用基类的
初始化构造函数B1(a),然后根据d, c, b成员在类中一个范围模快(如同一个public,或private)
中成员定义的顺序进行初始化,这里还需要注意的是初始化的依赖性的问题,具体参考
effective c++
hxq_dms 2007-03-14
  • 打赏
  • 举报
回复
与初始化列表中的排列顺序无关,是不是就指我所疑惑的B1(a),memberB2(d),memberB1(c),B2(b){ }这个顺序其实随便怎么写都可以,无论怎么写都混按照它本来应该的顺序执行,不会发生错误??
todototry 2007-03-14
  • 打赏
  • 举报
回复
类对象数据成员按照在类定义声明顺序进行构咱与成员初始化列表无联系
chenyu2202863 2007-03-14
  • 打赏
  • 举报
回复
构造函数的调用是先基类然后派生类,而调用析构函数的顺序先派生类然后基类
ckt 2007-03-14
  • 打赏
  • 举报
回复
如一楼所言
构造函数初始化列表的中的初始化顺序是按初始化的成员在类中定义的先后顺序进行初始化的。
nonamespace 2007-03-14
  • 打赏
  • 举报
回复
在这里哪个先写哪个后写不重要,但是要注意编译器初始化该类的过程,如DonaldKnuth(克努特)所说的,是按成员在类的定义中的顺序来初始化的,否则可能会引起莫名其妙的错误,更详细的解释请参照c++ primer中相关的章节。

64,637

社区成员

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

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