1.继承的语法
class 子类 : 继承方式 父类
子类 也称为 派生类
派生类的成员,包含两大部分:
一类是从基类继承过来的,一类是自己增加的成员
从基类继承过来的表现其共性,而新增的成员体现了其个性
父类 也称为 基类
2.继承方式
public:类的内部和外部都可以访问
protected:类内部和子类可以访问,但不能从外部直接访问
private:只能在类内部访问,不能在类外部或子类中直接访问
class Base
{
public:
int m_A;
protected:
int m_B;
private:
int m_C;
};
2.1公共继承
class Son1 : public Base
{
public:
void func()
{
m_A = 10; //父类中的公共权限成员 到子类中依然是公共权限
m_B = 10; //父类中的保护权限成员 到子类中依然是保护权限
//m_C = 10; //父类中的私有权限成员 子类访问不到
}
};
void test01()
{
Son1 s1;
s1.m_A = 100;
//s1.m_B = 100; //到Son1中 m_B是保护权限 类外访问不到
}
2.2 保护继承
子类中可以访问,类外访问不到
class Son2 : protected Base
{
public:
void func()
{
m_A = 10; //父类中的公共权限成员 到子类中是保护权限
m_B = 10; //父类中的保护权限成员 到子类中依然是保护权限
//m_C = 10; //父类中的私有权限成员 子类访问不到
}
};
void test02()
{
Son2 s2;
//s2.m_A = 100; //到Son2中 是保护权限 类外访问不到
//s1.m_B = 100; //到Son2中 是保护权限 类外访问不到
}
2.3私有继承
class Son3 : private Base
{
public:
void func()
{
m_A = 10; //父类中的公共权限成员 到子类中变为 私有成员
m_B = 10; //父类中的保护权限成员 到子类中变为 私有成员
//m_C = 10; //父类中的私有权限成员 子类访问不到
}
};
3.构造和析构
class Base
{
public:
Base()
{
cout << "Base构造函数" << endl;
}
~Base()
{
cout << "Base析构函数" << endl;
}
};
class Son : public Base
{
public:
Son()
{
cout << "Son构造函数" << endl;
}
~Son()
{
cout << "Son析构函数" << endl;
}
};
void test01()
{
Son s;
}
先构造父亲,再构造子类,析构的顺序与构造的顺序相反
结果:
4.菱形继承
1.1正常继承
//动物类
class Animal{
public:
int m_Age;
};
//羊类
class Sheep : public Animal{};
//驼类
class Camel : public Animal{};
//羊驼类
class SheepCamel : public Sheep,public Camel{};
void test01(){
SheepCamel sc;
sc.Sheep::m_Age = 18;
sc.Camel::m_Age = 38;
//加作用域进行区分
cout << "sc.Sheep::m_Age = " << sc.Sheep::m_Age << endl;
cout << "sc.Camel::m_Age = " << sc.Camel::m_Age << endl;
}
运行结果:
1.2虚继承
利用虚继承 可以解决菱形继承的问题
继承之前加上关键字 virtual 变成虚继承
Animal类成为虚基类
vbptr:virtual base pointer(虚基类指针)
//动物类
class Animal{
public:
int m_Age;
};
//羊类
class Sheep : virtual public Animal{};
//驼类
class Camel : virtual public Animal{};
//羊驼类
class SheepCamel : public Sheep,public Camel{};
void test01(){
SheepCamel sc;
sc.Sheep::m_Age = 18;
sc.Camel::m_Age = 38;
//加作用域进行区分
cout << "sc.Sheep::m_Age = " << sc.Sheep::m_Age << endl;
cout << "sc.Camel::m_Age = " << sc.Camel::m_Age << endl;
}
运行结果: