问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

C++ 派生类构造函数的调用顺序的一道题目

发布网友 发布时间:2023-04-12 01:13

我来回答

5个回答

热心网友 时间:2023-09-29 03:47

答案:
类A的默认构造函数
类A的默认构造函数
类B的默认构造函数
类A的默认构造函数
类A的默认构造函数
类B的默认构造函数
类A的构造函数
类A的构造函数
类B的构造函数
类B的析构函数
类A的析构函数
类A的析构函数
类A的构造函数
类A的构造函数
类B的构造函数
类B的析构函数
类A的析构函数
类A的析构函数
1,3,2
4,6,5
类B的析构函数
类A的析构函数
类A的析构函数
类B的析构函数
类A的析构函数
类A的析构函数

首先:“类A的默认构造函数
类A的默认构造函数
类B的默认构造函数
类A的默认构造函数
类A的默认构造函数
类B的默认构造函数”
来自B b1[2]; 的定义
“类A的构造函数
类A的构造函数
类B的构造函数
类B的析构函数
类A的析构函数
类A的析构函数"
是源自b1[0]=B(1,2,3); 的初始化,注意析构顺序与构造顺序相反。
同理b1[1]=B(4,5,6); 产生接下来的六行
最后输出out产生余下的输出

构造函数有两种形式:一种是由编译器自动生成的缺省构造函数;另一种是用户自定义构造函数。缺省构造函数用户不必定义函数体,编译器自动为对象进行初始化,即为每个数据成员赋值零或空值。而用户自定义构造函数的函数体需要用户自己定义,因此用户自定义构造函数不但可以初始化类中的数据成员,而且还可以设计一个程序段在对象创建时被执,如对象创建提示语句。
关于构造函数调用顺序的说明
我们来看下面一段代码:
class B1
{
public:
B1(int i) {cout<<"constructing B1 "<<i<<endl;}
};
class B2
{
public:
B2(int j) {cout<<"constructing B2 "<<j<<endl;}
};
class B3
{
public:
B3( ){cout<<"constructing 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;
};
void main( )
{ C obj(1,2,3,4); }
运行后的结果如下:
constructing B2 2
constructing B1 1
constructing B3 *
constructing B1 3
constructing B2 4
constructing B3 *
为什么会有以上的结果?
众所周知构造函数的执行次序如下:
调用基类构造函数,调用顺序按照他们的继承时声明的顺序。
调用内嵌成员对象的构造函数,调用顺序按照他们在类中声明的顺序。
派生类的构造函数体中的内容。
析构函数的调用顺序相反。
那么再来看以上的例子就很容易理解了。B2、B1、B3是C的基类,按照上述的顺序,我们先要构造基类,然后才是子对象,最后是其本身的构造函数所以先要执行这三个类的构造函数。在构造时按照他们在类中的顺序,首先调用B2的构造函数
B2(int j) {cout<<"constructing B2 "<<j<<endl;}
由于在默认参数列表
C(int a, int b, int c, int d):B1(a),memberB2(d),memberB1(c),B2(b){}
中,将b的值传给了B2的构造函数,b为2,故打印出:
constructing B2 2
接下来要构造的是B1了。显然在C的默认参数构造列表中将a的值传给了B1,
所以打印出:
constructing B1 1
B3在构造时没有传递参数,调用B3( ){cout<<"constructing B3 *"<<endl;}
打印出:
cout<<"constructing B3 *
这时基类的构造函数已经执行完毕,接着该处理内嵌成员对象的构造函数了。
我们看到C类有三个对象:B1 memberB1;B2 memberB2;B3 memberB3;,按照构造函数的调用顺序,我们需要按照他们在类中声明的顺序来分别构造memberB1、memberB2、 memberB3。在默认的参数列表中,用c来构造了memberB1,用d来构造memberB2,
故打印出:
constructing B1 3
constructing B2 4
constructing B3 *
最后调用本身的构造函数,由于函数体为空,故什么也没有打印出来。
总结下来,我们必须明确的是当一个类继承与基类,并且自身还包含有其他类的成员对象的时候,构造函数的调用顺序为:调用基类的构造函数->调用成员对象的构造函数->调用自身的构造函数。构造函数的调用次序完全不受构造函数初始化列表的表达式中的次序影响,与基类的声明次数和成员对象在函数中的声明次序有关。
再如:
#include<iostream.h>
class A
{
protected:
char c;
public:
A(char ch)
{
c=ch;
cout<<"c="<<c<<endl;
cout<<"类A构造函数被调用"<<endl;
}
~A()
{
cout<<"类A析构函数被调用"<<endl;
}
};
class B
{
protected:
int i;
public:
B(int j)
{
i=j;
cout<<"i="<<i<<endl;
cout<<"类B构造函数被调用"<<endl;
}
~B()
{
cout<<"类B析构函数被调用"<<endl;
}
};
class C:public A,B
{
private:
int k;
public:
C(char ch,int ii,int kk):A(ch),B(ii),k(kk)
{
cout<<"k="<<k<<endl;
cout<<"类C构造函数被调用"<<endl;
}
~C()
{
cout<<"类C析构函数被调用"<<endl;
}
};
void main()
{
C A('B',10,15);
}
输出
c=B
类A构造函数被调用
i=10
类B构造函数被调用
k=15
类C构造函数被调用
类C析构函数被调用
类B析构函数被调用
类A析构函数被调用

热心网友 时间:2023-09-29 03:47

#include<iostream.h>

class A

{

public:

     A()

     {

          a=0;

          cout<<"类A的默认构造函数"<<endl;

     }

     A(int i)

     {

          a=i;

          cout<<"类A的构造函数"<<endl;

     }

     ~A()

     {

          cout<<"类A的析构函数"<<endl;

     }

     void out() const

     {

          cout<<a<<",";

     }

     int geta()

     {

           return a;

     }

private:

     int a;

};

class B:public A

{

public:

     B()

     {

           b=0;

           cout<<"类B的默认构造函数"<<endl;

     }

     B(int i,int j,int k);

     ~B()

     {

           cout<<"类B的析构函数"<<endl;

     }

     void out();

private:

     int b;

     A a1;           //成员数据为A的对象,需要用初始化列表

};

B::B(int i,int j,int k):A(i),a1(j)   //成员数据为A的对象,需要用初始化列表,此处就调用一次A的默认构造函数

{

     b=k;

     cout<<"类B的析构函数"<<endl;   //最好改为cout<<"类B的构造函数"<<endl;,容易理解

}

void B::out()

{

     A::out();

     cout<<b<<","<<a1.geta()<<endl;

}

void main()

{

     B b1[2];    //等同于B b1[2] = {B(),B()},调用默认的构造函数,基类A优先调用,后B

     b1[0]=B(1,2,3);   //赋值操作,先新建B(1,2,3),后销毁已给b1的数据,清除内存,再重新赋值。即B(1,2,3)就如同上步的操作(调用指定的构造函数),b1调用默认析构函数(派生类B优先,后基类A)

     b1[1]=B(4,5,6);   //同上

     for(int i=0;i<2;i++)

  b1[i].out();

具体答案如下:

热心网友 时间:2023-09-29 03:48

答案:
类A的默认构造函数
类A的默认构造函数
类B的默认构造函数
类A的默认构造函数
类A的默认构造函数
类B的默认构造函数
类A的构造函数
类A的构造函数
类B的构造函数
类B的析构函数
类A的析构函数
类A的析构函数
类A的构造函数
类A的构造函数
类B的构造函数
类B的析构函数
类A的析构函数
类A的析构函数
1,3,2
4,6,5
类B的析构函数
类A的析构函数
类A的析构函数
类B的析构函数
类A的析构函数
类A的析构函数
首先:“类A的默认构造函数
类A的默认构造函数
类B的默认构造函数
类A的默认构造函数
类A的默认构造函数
类B的默认构造函数”
来自Bb1[2];的定义
“类A的构造函数
类A的构造函数
类B的构造函数
类B的析构函数
类A的析构函数
类A的析构函数"
是源自b1[0]=B(1,2,3);的初始化,注意析构顺序与构造顺序相反。
同理b1[1]=B(4,5,6);产生接下来的六行
最后输出out产生余下的输出
构造函数有两种形式:一种是由编译器自动生成的缺省构造函数;另一种是用户自定义构造函数。缺省构造函数用户不必定义函数体,编译器自动为对象进行初始化,即为每个数据成员赋值零或空值。而用户自定义构造函数的函数体需要用户自己定义,因此用户自定义构造函数不但可以初始化类中的数据成员,而且还可以设计一个程序段在对象创建时被执,如对象创建提示语句。
关于构造函数调用顺序的说明
我们来看下面一段代码:
classB1
{
public:
B1(inti){cout<<"constructingB1"<<i<<endl;}
};
classB2
{
public:
B2(intj){cout<<"constructingB2"<<j<<endl;}
};
classB3
{
public:
B3(){cout<<"constructingB3*"<<endl;}
};
classC:publicB2,publicB1,publicB3
{
public:
C(inta,intb,intc,intd):B1(a),memberB2(d),memberB1(c),B2(b){}
private:
B1memberB1;
B2memberB2;
B3memberB3;
};
voidmain()
{Cobj(1,2,3,4);}
运行后的结果如下:
constructingB22
constructingB11
constructingB3*
constructingB13
constructingB24
constructingB3*
为什么会有以上的结果?
众所周知构造函数的执行次序如下:
调用基类构造函数,调用顺序按照他们的继承时声明的顺序。
调用内嵌成员对象的构造函数,调用顺序按照他们在类中声明的顺序。
派生类的构造函数体中的内容。
析构函数的调用顺序相反。
那么再来看以上的例子就很容易理解了。B2、B1、B3是C的基类,按照上述的顺序,我们先要构造基类,然后才是子对象,最后是其本身的构造函数所以先要执行这三个类的构造函数。在构造时按照他们在类中的顺序,首先调用B2的构造函数
B2(intj){cout<<"constructingB2"<<j<<endl;}
由于在默认参数列表
C(inta,intb,intc,intd):B1(a),memberB2(d),memberB1(c),B2(b){}
中,将b的值传给了B2的构造函数,b为2,故打印出:
constructingB22
接下来要构造的是B1了。显然在C的默认参数构造列表中将a的值传给了B1,
所以打印出:
constructingB11
B3在构造时没有传递参数,调用B3(){cout<<"constructingB3*"<<endl;}
打印出:
cout<<"constructingB3*
这时基类的构造函数已经执行完毕,接着该处理内嵌成员对象的构造函数了。
我们看到C类有三个对象:B1memberB1;B2memberB2;B3memberB3;,按照构造函数的调用顺序,我们需要按照他们在类中声明的顺序来分别构造memberB1、memberB2、memberB3。在默认的参数列表中,用c来构造了memberB1,用d来构造memberB2,
故打印出:
constructingB13
constructingB24
constructingB3*
最后调用本身的构造函数,由于函数体为空,故什么也没有打印出来。
总结下来,我们必须明确的是当一个类继承与基类,并且自身还包含有其他类的成员对象的时候,构造函数的调用顺序为:调用基类的构造函数->调用成员对象的构造函数->调用自身的构造函数。构造函数的调用次序完全不受构造函数初始化列表的表达式中的次序影响,与基类的声明次数和成员对象在函数中的声明次序有关。
再如:
#include<iostream.h>
classA
{
protected:
charc;
public:
A(charch)
{
c=ch;
cout<<"c="<<c<<endl;
cout<<"类A构造函数被调用"<<endl;
}
~A()
{
cout<<"类A析构函数被调用"<<endl;
}
};
classB
{
protected:
inti;
public:
B(intj)
{
i=j;
cout<<"i="<<i<<endl;
cout<<"类B构造函数被调用"<<endl;
}
~B()
{
cout<<"类B析构函数被调用"<<endl;
}
};
classC:publicA,B
{
private:
intk;
public:
C(charch,intii,intkk):A(ch),B(ii),k(kk)
{
cout<<"k="<<k<<endl;
cout<<"类C构造函数被调用"<<endl;
}
~C()
{
cout<<"类C析构函数被调用"<<endl;
}
};
voidmain()
{
CA('B',10,15);
}
输出
c=B
类A构造函数被调用
i=10
类B构造函数被调用
k=15
类C构造函数被调用
类C析构函数被调用
类B析构函数被调用
类A析构函数被调用

热心网友 时间:2023-09-29 03:48

知识点一、
子类对象的构造,是先构造父类对象,然后构造子类对象。
子类对象的析构,先运行子类对象的析构函数,再运行父类对象的析构函数,刚刚好喝对象的构造相反。
知识点二、
构造对象时,若没有制定参数,那么会通过默认构造函数初始化对象。如果有参数,那么会通过参数类型自动选择构造函数进行对象的初始化。这里和函数的重载是一样的。
另外,还要注意到类B中有一个A a1;的私有变量声明。

答案:
类A的默认构造函数
类A的默认构造函数
类B的默认构造函数
类A的默认构造函数
类A的默认构造函数
类B的默认构造函数
类A的构造函数
类A的构造函数
类B的构造函数
类B的析构函数
类A的析构函数
类A的析构函数
类A的构造函数
类A的构造函数
类B的构造函数
类B的析构函数
类A的析构函数
类A的析构函数
1,3,2
4,6,5
类B的析构函数
类A的析构函数
类A的析构函数
类B的析构函数
类A的析构函数
类A的析构函数

热心网友 时间:2023-09-29 03:49

类A的默认构造函数
类A的默认构造函数
类B的默认构造函数
类A的默认构造函数
类A的默认构造函数
类B的默认构造函数
类A的构造函数
类A的构造函数
类B的析构函数
类B的析构函数
类A的析构函数
类A的析构函数
类A的构造函数
类A的构造函数
类B的析构函数
类B的析构函数
类A的析构函数
类A的析构函数
1,3,2
4,6,5
类B的析构函数
类A的析构函数
类A的析构函数
类B的析构函数
类A的析构函数
类A的析构函数
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
RDL是什么意思 报税软件是什么意思 某公司的财务报表管理软件属于 报表系统指的是什么? 怎么玩真三最好?我是新手选什么英雄最好? 真三新手玩什么英雄好? 最近玩魔兽真三,想请问一下高手,初期用什么英雄最好,新手攻略 新手玩真三选什么英雄好啊 ...离泡还有一段距离的地方好几片红,红的地方又疼又痒的,怎么办... 眼角出了好多小水疱.医生说是疱疹.怎么办 C++题目构造函数和析构函数 第五大题第二小题,答案要先构造函数F(X)=f(x)-x!不太懂为什么这样设 得力打印机和惠普打印机的耗材哪个便宜 清明节有孩子不能上坟能在家里烧么 清明去墓地供奉后在家还可以供吗 win2008远程电脑不支持受限管理模式 2021年12月浙江中高风险地区最新名单是哪些 地铁跑酷如何用虫虫助手刷金币钥匙 快手ta是什么意思 淘宝里的亲是什么意思 鞋套商贸 淘宝里店主常说的“亲”是什么意思? 山东省考面试比例 山东省省考进面比例 山东公务员录取比例是多少 公务员考试人数和录取比例 山东省考开考比例 山东省事业单位省考比例 昆明市糖业烟酒公司哪年改革 主板供电不稳会导致过不了自检吗 闲林耳机厂在什么地方 求证高数证明题,谢谢。 易牙颡首是什么意思 请问一下古代历史上有名的大厨有谁啊 易牙是哪个年代 易牙是哪谁的厨子 1到198的阶加怎么算 一阶泰勒公式怎么推导出二阶的? 日式风格logo设计意义? 日本公司世嘉logo设计理念是什么? 中国旅游日的标志图案字体演变? 中国品牌日标志的构图要素和寓意? 世界读书日标志图及寓意? 新农合在哪些医院看病可以报销 新型农村合作医疗 异地就医在哪里报销农村合作医疗 抖音上火的粤语歌什么情 水中花抖音男生是谁唱 叫花鸡的名字是怎么来的 叫花鸡是如何得来的传说故事 抓娃娃机的技巧怎么才能抓上来 敲磨的拼音狐敲磨的拼音是什么