172继承性和派生类_单继承的构造函数和析构函数
173继承性和派生类_10_6的执行结果
174继承性和派生类_10_7程序分析
175继承性和派生类_子类型兼容
176继承性和派生类_多继承
10.2 单继承
10.2.2 派生类的构造函数和析构函数
从一个基类中派生的继承,称为单继承在单继承中,每个类可以生成多个派生类,每个派生类只能有一个基类。
重点讨论:
单继承中派生类的构造函数和析构函数的构造
回顾:
构造函数的功能,在创建对象的时候,用给定的值对对象进行初始化。
构造函数的特点:
1)特殊的成员函数,与类同名可以在类内也可以在类外进行定义
2)构造函数没有函数返回值类型
3)构造函数可以重载,可以定义多个参数的构造函数
4)在创建一个对象的时候系统自动调用
析构函数的功能,用来释放一个对象。
析构函数特点:
1)特殊的成员函数,与类同名,前面有个~,可以在类内也可以在类外进行定义
2)析构函数没有函数返回值类型。
3)一个类中只有一个析构函数
4)函数结束的时候,系统自动调用析构函数
1. 派生类构造函数格式如下:
〈函数名〉(〈总参数表〉):〈基类构造函数〉(〈参数表1〉),〈子对象名〉(〈参数表2>),…
{〈函数体〉}
基类的构造函数不能被继承,执行该构造函数的顺序是先执行基类构造函数,如有子对象时,再执行子对象类的构造函数,最后执行该派生类构造函数的函数体。
2. 析构函数
析构函数和构造函数都不能被继承。因此在执行派生类的析构函数时,先调用派生类析构函数的函数体,再调用子对象类析构函数,最后调用基类析构函数。
参见[例10-6]、[例10-7]
构造函数的执行顺序:基类的构造函数,子对象的构造函数,派生类的构造函数
3.派生类构造函数使用中应该注意的问题
(1)派生类构造函数的定义中可以省略对基类构造函数的调用,其条件是在基类中必须有默认的构造函数或者根本没有定义构造函数
include
class A
{
public:
A() {a=0;}
A(int i) { a=i;}
void print() { cout<
private:
int a;
};
class B:public A
{
public:
B() {b1=b2=0;}
B(int i) {b1=i;b2=0;}
B(int i,int j,int k):A(i),b1(j),b2(k) { }
void print() {
A::print();
cout<
private:
int b1,b2;
};
void main()
{B d1;
B d2(5);
B d3(4,5,6);
d1.print();
d2.print();
d3.print();
}
当基类的构造函数使用一个或多个参数时,则派生类定义的构造函数必须包含基类的构造函数,提供将参数传递给基类构造函数的途径.在有的情况下,派生类构造函数的函数体可能为空,仅起到参数传递的作用
class B
{public:
B(int i, int j) {b1=i; b2=j;}
…
private:
int b1, b2;
};
class D: public B
{public:
D(int i, int j, int k, int l, int m);
private:
int d1;
B bb;
};
D∷D(int i, int j ,int k, int l, int m):B(i, j), bb(k, l),d1(m)
{
}
10.2.3 子类型和赋值兼容规则
1. 子类型
有一类型A,它至少包含有另一种类型B的所有行为,则称类型A是类型B的子类型。
也可以说类型A适应类型B。子类型或者说类型适应是不可逆的。
例如,在公有继承方式下,派生类是基类的子类型,派生类适应于基类。派生类的对象是基类的对象。
class A
{public:
void Print() const {cout<
};
class B:public A
{public:
void f(){ }
};
void f1(const A &r)
{r.Print();}
void main()
{B b;
2. 赋值兼容规则
在公有继承方式下,派生类是基类的子类型。
此时满足下述赋值兼容规则。
① 派生类的对象可给基类对象赋值
② 派生类的对象可用来对基类对象的引用进行初始化
③ 派生类的对象地址值可用来给基类的指针赋值
10.3 多继承
10.3.1多继承的概念
单继承的很多概念适用于多继承,多继承不同于单继承的是它具有两个或两个以上的基类。
多继承下派生类的定义格式如下:
class :,
{
};
多继承中派生类与多个基类之间的关系
class A
{
…
};
class B
{
…
};
class C:public A, public B
{
…
};
10.3.2 多继承的构造函数和析构函数
1. 多继承派生类构造函数的定义格式
〈函数名〉(〈总参数表〉):〈基类名1〉(〈参数表1〉)、〈基类名2〉(〈参数表2〉)…
〈子对象名〉(〈参数表〉),…
{〈派生类构造函数的函数体〉}
构造函数的执行顺序基本上与单继承构造函数的执行顺序相同,
所不同的是:
多个基类构造函数的执行顺序是按定义多继承类时所给定的基类的顺序。
多继承派生类的析构函数中也应包含其基类的析构函数
该析构函数的执行顺序与其构造函数的执行顺序相反。
#include
class B1
{
public:
B1(int i)
{
b1=i;
cout<
}
void print() { cout<
private:
int b1;
};
class B2
{
public:
B2(int i)
{
b2=i;
cout<
}
void print() { cout<
private:
int b2;
};
class B3
{
public:
B3(int i)
{
b3=i;
cout<
}
int getb3() { return b3;}
private:
int b3;
};
class A:public B2,public B1
{public:
A(int i,int j,int k,int l):B1(i),B2(j),bb(k)
{ a=l;
cout<
void print()
{
B1::print();
B2::print();
cout<