目录
派生类的生成过程
派生类的构造函数与析构函数:
构造函数:
派生类+组合类的构造和析构:
构造函数和析构函数调用顺序:
派生类的生成过程
三步骤:
吸收基类(父类)成员:实现代码重用;
派生类继承了基类除了构造函数、析构函数以外的所有成员函数。
改造基类(父类)成员:改变原基类成员的访问控制权限、同名覆盖原基类的成员;
同名覆盖:在派生类中定义一个与基类同名的成员,派生类的成员将基类原成员隐藏;
对原基类被覆盖成员的访问方式:
//访问被覆盖的A类成员: A::show();
新增派生类(子类)成员:对源代码进行扩充。
以派生类的实际需求新增加数据成员和成员函数,以增强派生类的功能
派生类的构造函数与析构函数:
因为派生类无法继承基类的构造函数与析构函数,且派生类成员由继承的基类成员、派生类新增成员共同构成,我们需自行完成构造函数实现对继承成员及新增成员的初始化、析构函数释放成员。
构造函数:
我们可以通过基类构造函数,初始化继承的基类成员
构造函数格式:
派生类名:: 派生类名( 参数列表 ):基类名(初始化列表),新成员(参数)
{};
eg:
//继承与派生的生成过程
#include <iostream>
#include <string>
using namespace std;
class A //基类
{
public:
A(int i) :a(i) { cout << "A 的构造函数" << endl; };
A() :a() { cout << "A 的默认!构造函数" << endl; };
~A() { cout << "A 的析构函数" << endl; };
void show()
{
cout << "a=" << a<<endl;
}
private:
int a;
};
class B :public A
{
public:
B(int j) :b(j)
{ cout << "B 的构造函数" << endl; }
//等同与:
//B(int j):A(),b(j)
//{cout << "A 的构造函数" << endl; }
B(int i, int j) :A(i), b(j)
{ cout << "B 的构造函数" << endl; }
//同名覆盖:
void show()
{
//访问基类原被覆盖成员:
A::show();
cout << "b=" << b << endl;
}
~ B() { cout << "B 的析构函数" << endl; }
private :
int b;//新增加成员
};
int main()
{
A a{9};
a.show();
B b{7,8};
b.show();
return 0;
}
注意:
- 基类的构造函数必须在初始化列表内完成:
- 进入构造函数大括号内说明构造函数的功能已经实现,而基类未初始化
- 基类如有默认构造函数时,可以省略不写
- 该构造函数初始化,自动跳转默认构造函数
输出:
总结:派生类的构造:先调用基类构造函数、再调用派生类的构造函数,析构函数则与派生顺序相反(形成对称)
析构函数:
~类名();无差别,特殊情况区别处理;
派生类+组合类的构造和析构:
派生类:继承所得类
组合类:新增加的成员对象是另一个类的对象
//继承与派生的生成过程
//这是配置好的模板文件
#include <iostream>
#include <string>
using namespace std;
class X
{
public:
X(int x) :c(x)
{
cout << "X(int x)构造函数" << endl;
}
~X()
{
cout << "~X()析构函数" << endl;
}
void show()
{
cout << "c=" << c << endl;
}
private:
int c;
};
class A //基类
{
public:
A(int i) :a(i) { cout << "A 的构造函数" << endl; };
A() :a() { cout << "A 的默认!构造函数" << endl; };
~A() { cout << "A 的析构函数" << endl; };
void show()
{
cout << "a=" << a<<endl;
}
private:
int a;
};
派生类:
class B :public A
{
public:
B(int i, int x) : b(i), c(x)
{
cout << "B 的构造函数" << endl;
}
//等同与:
//B(int j,int x):A(),b(j),c(x)
//{cout << "A 的构造函数" << endl; }
B(int i,int j,int x):A(i),b(j),c(x)
{ cout << "B 的构造函数" << endl; }
//同名覆盖:
void show()
{
//访问基类原被覆盖成员:
A::show();
cout << "b=" << b << endl;
c.show();
}
~ B() { cout << "B 的析构函数" << endl; }
private :
int b;//新增加成员
X c; //新增组合类的成员
};
int main()
{
/*A a{9};
a.show();*/
B b{7,8,9};
b.show();
return 0;
}
输出:
构造函数和析构函数调用顺序:
派生类构造函数执行顺序一般是:
基类(父类)、组合类、派生类
具体如下:
(1)先调用基类的构造函数;
(2)然后按照数据成员的声明顺序,依次调用数据成员的构造函数或初始化数据成员;
(3)最后执行派生类构造函数的函数体。
注意:构造函数的执行顺序只与成员声明的顺序有关,而与初始化表中各项的排列顺序无关。
注意:派生类析构函数执行时将自动调用基类、组合类成员对象的析构函数
析构函数执行顺序:
派生类、组合类、基类
析构函数与构造函数顺序相反,形成对称