一.继承与派生的概念及作用
一个新定义的类具有某个或某些旧类的功能和数据成员,但不完全相同,额外添加了一些功能或数据成员。
旧类:基类,父类 新类:派生类,子类
单一继承:派生类只有一个基类
多重继承:派生类有多个基类
作用:提高代码的可重用性
二.派生类的定义与访问控制
派生类的定义语法:
class 派生类名:继承方式 基类名[,继承方式 基类名,继承方式 基类名......]
{
派生类比基类新增的数据成员和成员函数定义
};
继承方式缺省默认private
基类的构造函数和析构函数不能被继承
三种继承方式 public protected private 的区别:
共性:都不能继承基类的private成员
区别:
public继承后基类成员属性不变
protected 继承后 public 和protected都变成protected
private 继承后 public 和protected都变成private
三.派生类的构造与析构
构造函数与析构函数的调用次序:
#include<iostream>
using namespace std;
class Member {
public:
Member() {
cout << "constructing Member\n";
}
~Member() {
cout << "deconstrucing Member\n";
}
};
class Base {
public:
Base() {
cout << "construcing Base\n";
}
~Base() {
cout << "deconstrucing Base\n";
}
};
class Drived :Base{
private:
Member member1;
public:
Drived() {
cout << "constructing Drived\n";
}
~Drived() {
cout << "deconstructing Drived\n";
}
};
int main() {
Drived obj1;
return 0;
}
construcing Base//运行结果
constructing Member
constructing Drived
deconstructing Drived
deconstrucing Member
deconstrucing Base
可以看出 定义一个派生类对象时,析构函数调用次序如下:
1.基类的构造函数
2.派生类对象成员的构造函数(按定义排序)
3.派生类构造函数
如果基类和对象成员的构造函数有参数,需要在派生类构造函数的初始化列表调用这些构造函数
格式如下:
派生类名(总形式参数表):基类(形式参数表1),基类(形式参数表2),其他初始化项......
{
//派生类自身数据成员的初始化
}
有参构造函数的调用演示
#include<iostream>
using namespace std;
class Base {
private:
int x;
public:
Base(int i) {
x = i;
cout << "constructing Base\n";
}
void show() {
cout << "x=" << x << endl;
}
};
class Derived :public Base
{
private:
Base d;
public:
Derived(int i) :Base(i), d(i)
{
cout << "constructing Derived\n";
}
};
int main() {
Derived obj(1);
obj.show();
return 0;
}
constructing Base
constructing Base
constructing Derived
x=1
多重继承下构造函数与析构函数的调用
#include<iostream>
using namespace std;
class grand {
private:
int age1;
public:
grand(int n):age1(n) {
cout << "constructing grand\n";
cout << age1<<endl;
}
~grand() {
cout << "deconstructing grand\n";
}
};
class father:public grand {
private:
int age2;
public:
father(int n, int m) :grand(n), age2(m)
{
cout << "constructing father\n";
cout << age2 << endl;
}
~father() {
cout << "deconstructing father\n";
}
};
class mother {
private:
int age3;
public:
mother(int p) :age3(p) {
cout << "constructing mother\n";
cout << age3<<endl;
}
~mother() {
cout << "deconstructing mother\n";
}
};
class son :public father, public mother {
private:
int age;
public:
son(int m, int b, int p, int l) :father(m, b), mother(p), age(l) {
cout << "constructing son\n";
cout << age << endl;
}
~son() {
cout << "deconstructing son\n";
}
};
int main() {
son son1(90,60,50,20);
return 0;
}
constructing grand
90
constructing father
60
constructing mother
50
constructing son
20
deconstructing son
deconstructing mother
deconstructing father
deconstructing grand
多层派生的关系结构,每个派生类只需要负责直接基类构造函数的调用
调用构造函数的顺序以派生类定义时为准,而不是派生类的构造函数初始化列表的顺序