目录
继承的好处:减少重复代码
语法: class 子类:继承方式 父类
继承方式
- 公共继承
- 保护继承
- 私有继承
父类中所有非静态成员属性都被子类继承了,私有成员访问不到是因为被编译器隐藏了
派生类对基类成员的访问形式主要有以下两种:
- 内部访问:由派生类中新增的成员函数对基类继承来的成员的访问。
- 对象访问:在派生类外部,通过派生类的对象对从基类继承来的成员的访问。
继承中构造和析构顺序
#include <iostream>
#include <string>
using namespace std;
class A{
public:
A() {
cout << "A类对象构造中..." << endl;
}
~A() {
cout << "析构A类对象..." << endl;
}
};
class B : public A{
public:
B() {
cout << "B类对象构造中..." << endl;
}
~B(){
cout << "析构B类对象..." << endl;
}
};
int main() {
B b;
return 0;
}
A类对象构造中...
B类对象构造中...
析构B类对象...
析构A类对象...
继承同名成员处理方式
- 访问子类同名成员,直接访问即可(子类对象可以直接访问子类成员)
- 访问父类同名成员,需要加作用域(子类对象加作用域可以访问父类同名成员)
同名成员属性:
class Base {
public:
Base() {
A = 100;
}
int A;
};
class Son :public Base {
public:
int A;
Son() {
A = 200;
}
};
int main() {
Son p;
cout << p.A;
cout << p.Base::A;
}
同名成员函数:
如果子类中出现和父类同名的成员函数,子类的同名成员会隐藏掉父类中所有同名成员函数(所以也不能靠参数来区分了,想调用父类函数时必须写上作用域)
class Base {
public:
void func() {
cout << "Base" << endl;
}
};
class Son :public Base {
public:
void func() {
cout << "Son" << endl;
}
};
int main() {
Son p;
p.Base::func();
p.func();
}
同名静态成员处理方式
- 访问子类同名成员,直接访问即可
- 访问父类同名成员,需要加作用域
同名静态成员属性
- 通过对象访问 Son.Base::A
- 通过类名访问 Son::Base::A(第一个双冒号:通过类名的方式来访问,第二个双冒号:访问Base作用域下)
同名静态函数
- 通过对象访问 Son.func()
- 通过类名访问 Son::Base::func() (第一个双冒号:通过类名的方式来访问,第二个双冒号:访问Base作用域下)
多继承
语法: class 子类:继承方式 父类1,继承方式 父类2
当父类中出现了同名成员,需要加作用域区分 s.Base1::A s.Base2::A
菱形继承
- 两个派生类继承同一个基类
- 又有某个类同时继承这两个派生类
两个父类拥有相同数据,需要加以作用域区分
一个数据有一份就可以,而菱形继承导致数据有两份,资源浪费
利用虚继承可以解决菱形继承的问题:
在继承之前加上关键字Virtual变为虚继承
此时Animal类称为虚基类
原本:
变成虚继承:
这样子相当于只有一个Age了