目录
- 一、程序及输出
- 1.1 构造、析构顺序
- 1.2 默认构造函数
- 1.3 显示调用父类中的其他构造函数
- 二、分析与总结
一、程序及输出
1.1 构造、析构顺序
先调用父类构造,再调用其他成员构造, 再调用自身构造 ,析构的顺序与构造相反
#include<iostream>
using namespace std;
class Base1
{
public:
Base1()
{
cout << "Base1的构造函数调用" << endl;
}
~Base1()
{
cout << "Base1的析构函数调用" << endl;
}
};
class Other
{
public:
Other()
{
cout << "Other的构造函数调用" << endl;
}
~Other()
{
cout << "Other的析构函数调用" << endl;
}
};
class Son1 :public Base1
{
public:
Son1()
{
cout << "Son1的构造函数调用" << endl;
}
~Son1()
{
cout << "Son1的析构函数调用" << endl;
}
Other other;
};
void test01()
{
Son1 s; //先调用父类构造,再调用其他成员构造, 再调用自身构造 ,析构的顺序与构造相反
}
int main(){
test01();
system("pause");
return EXIT_SUCCESS;
}
输出:
1.2 默认构造函数
如果派生类没有定义任何构造函数,编译器会自动生成默认构造函数。默认构造函数会自动调用基类的默认构造函数。
#include<iostream>
using namespace std;
class Base2
{
public:
Base2() {
this->m_A = 10;
cout << "Base2的默认构造函数调用" << endl;
}
Base2(int a)
{
this->m_A = a;
cout << "Base2的构造函数调用" << endl;
}
int m_A;
};
class Son2 :public Base2
{
public:
};
void test02()
{
Son2 s;
cout << s.m_A << endl;
}
int main(){
//test01();
test02();
system("pause");
return EXIT_SUCCESS;
}
输出:
1.3 显示调用父类中的其他构造函数
在 C++ 中,默认构造函数、析构函数、拷贝构造函数以及赋值运算符(operator=)是不会被子类继承下去的。
当子类没有定义这些函数时,编译器会自动生成默认的构造函数、析构函数、拷贝构造函数和赋值运算符。这些默认的函数会调用基类相应的函数,但并不是基类的这些函数被继承到子类中。
如果子类显式地定义了构造函数、析构函数、拷贝构造函数或赋值运算符,那么编译器不会再自动生成默认的函数。此时,如果希望子类调用基类相应的函数,可以在子类的定义中通过成员初始化列表或在构造函数体中显式调用基类的构造函数、析构函数或赋值运算符。
总结来说,父类中的默认构造函数、析构函数、拷贝构造函数和赋值运算符不会被子类继承下去,但可以通过子类的构造函数或赋值运算符中显式调用基类的相应函数来实现基类函数的调用。
#include<iostream>
using namespace std;
class Base2
{
public:
Base2(int a)
{
this->m_A = a;
cout << "Base2的构造函数调用" << endl;
}
int m_A;
};
class Son2 :public Base2
{
public:
Son2(int a = 1000 ) :Base2(a) //利用初始化列表语法 显示调用父类中的其他构造函数
{
cout << "Son2的构造函数调用" << endl;
}
};
void test02()
{
Son2 s;
cout << s.m_A << endl;
}
int main(){
test02();
system("pause");
return EXIT_SUCCESS;
}
输出:
二、分析与总结
构造函数执行顺序
:
构造函数的执行顺序是先基类构造函数,再派生类构造函数,最后按照声明顺序初始化成员变量。
析构函数执行顺序
:
析构函数的执行顺序是先派生类析构函数,再基类析构函数,按照继承关系的相反顺序销毁对象。
默认构造函数
:
如果派生类没有定义任何构造函数,编译器会自动生成默认构造函数。
默认构造函数会自动调用基类的默认构造函数。
派生类构造函数调用基类构造函数
:
派生类的构造函数应该调用基类的构造函数,确保基类部分被正确初始化。
可以使用成员初始化列表来调用基类构造函数,或在构造函数体中显式调用基类构造函数。