继承的好处 减少重复代码
语法 class 子类 :继承方式 父类
子类也称派生类
父类 也称 基类
继承方式
公共继承
保护继承
私有继承
class Base {
public:
int m_a;
private:
int m_b;
protected:
int m_c;
public:
void func(){
}
};
class classA : public Base {
public:
void test() {
m_a = 10;
//m_b = 20;//'m_b' is a private member of 'Base'
m_c = 11;
}
};
class classB : protected Base {
public:
void test(){
m_a = 10;
//m_b = 20;//'m_b' is a private member of 'Base'
m_c = 11;
}
};
class ClassC :private Base {
public:
void test(){
m_a = 10;
//m_b = 20;//'m_b' is a private member of 'Base'
m_c = 11;
}
};
void test5() {
classA a;
a.m_a = 20;
//a.m_b = 20;//'m_b' is a private member of 'Base'
//a.m_c = 4;//'m_c' is a protected member of 'Base'
classB b;
// b.m_a = 20;//'m_a' is a protected member of 'Base'
// b.m_b = 20;//'m_b' is a private member of 'Base'
// b.m_c = 4;//'m_c' is a protected member of 'Base'
ClassC c;
// c.m_a = 20;//'m_a' is a private member of 'Base'
// c.m_b = 20;//'m_b' is a private member of 'Base'
// c.m_c = 4;//'m_c' is a private member of 'Base'
}
继承中的对象模型
父类中所有非静态成员属性都会被子类继承下去
父类中私有成员属性是被编译器给隐藏了。因此是访问不到的 但是确实被继承了的
继承中构造和析构的顺序
构造函数调用顺序 先调用父类构造函数 再调用自己的构造函数
析构函数调用顺序 先调用自己的析构函数 再调用父类的析构函数
继承中同名成员处理方式
class Base {
public:
int m_a;
int m_d;
private:
int m_b;
protected:
int m_c;
public:
Base(){
m_d = 44;
cout << "Base" << endl;
}
~Base() {
cout << " ~Base" << endl;
}
void func(){
cout << "Base func" << endl;
}
void func(int a) {
cout << "Base func(int a)" << endl;
}
};
class classA : public Base {
public:
int m_d;
void test() {
m_a = 10;
//m_b = 20;//'m_b' is a private member of 'Base'
m_c = 11;
}
classA(){
m_d = 33;
}
~classA() {
}
void func(){
cout << "classA func" << endl;
}
};
void test55() {
classA a;
cout << "子类下 m_d = " << a.m_d << endl;
/// 子类访问从父类继承下来的同名成员 需要➕作用于
cout << "父类下 m_d = " << a.Base::m_d << endl;
// 调用子类中的同名函数
a.func();
// 调用父类中同名函数
a.Base::func();
//如果子类中出现和父类同名的成员函数 子类的同名成员函数会隐藏掉父类中所有同名成员函数
// 如果想访问到父类中被隐藏的同名成员函数 需要加作用域
a.Base::func(12);
}
子类对象可以直接访问到子类中同名成员
子类对象加作用域可以访问到父类同名成员
当子类与父类拥有同名的成员函数,子类会隐藏父类中同名成员函数 加作用域可以访问到父类中的同名函数
继承中同名静态成员处理
访问子类同名成员直接访问即可
访问父类同名成员需要加作用域
当子类与父类拥有同名的成员函数,子类会隐藏父类中同名成员函数 加作用域可以访问到父类中的同名函数
class Base {
public:
static int m_e;
private:
protected:
int m_c;
public:
static void func1() {
cout << "Base func1" << endl;
}
};
int Base::m_e = 100;
class classA : public Base {
public:
static int m_e;
classA(){
m_d = 33;
}
~classA() {
}
static void func1() {
cout << "classA func1" << endl;
}
};
int classA::m_e = 200;
void test55() {
classA a;
//访问静态成员
cout << "子类下 m_e = " << a.m_e << classA::m_e << endl;
cout << "父类下 m_e = " << a.Base::m_e << classA::Base::m_e << endl;
a.func1();
classA::func1();
a.Base::func1();
classA::Base::func1();
}
多继承
语法 class 子类 :继承方式 父类1,继承方式 父类2...
多继承可能会引发父类中有同名成员出现 需要加作用域区分
不太建议使用
class Base1{
public:
int m_a;
int m_b;
Base1() {
}
};
class Base2{
public:
int m_c;
int m_b;
Base2() {
}
};
class ClassE : public Base1, public Base2 {
public:
int m_d;
};
void test() {
ClassE e;
//同名成员
e.Base1::m_b;
e.Base2::m_b;
e.m_a;
}
菱形继承![](https://i-blog.csdnimg.cn/blog_migrate/3bf700e1062ba68395d928813adc1251.png)
class AnimalBase{
public:
int m_age;
};
/// 虚继承 : virtual 解决菱形继承 从基类继承下来的数据 出现多份的问题 (虚j基类表 指针偏移)
/// AnimalBase 虚基类
class Sheep : virtual public AnimalBase {
public:
};
class Tuo : virtual public AnimalBase {
public:
};
class TuoSheep : public Sheep, public Tuo {
public:
};