继承
继承
继承的语法:
class子类 : 继承方式 父类 {}
子类 -> 派生类 父类 -> 基类
继承方式
继承方式有三种:公共 public 、保护 protected、私有 private
子类访问权限表:
| 父类访问权限 | 父类访问权限 | 父类访问权限 | ||
|---|---|---|---|---|
| public | protected | private | ||
| 子类继承方式 | public | public | protected | 无法访问 |
| 子类继承方式 | protected | protected | protected | 无法访问 |
| 子类继承方式 | private | private | private | 无法访问 |
- public: 类内可以访问,类外可以访问
- protected: 类内可以访问,类外不可访问,子类可以访问
- private: 类内可以访问,类外不可访问,子类不可访问
测试子类访问权限:
#include<iostream>
using namespace std;
class Animal {
private:
int m_pri;
protected:
int m_pro;
public:
int m_pub;
};
class Cat : public Animal {//public继承
public:
Cat() {
m_pub = 1;
m_pro = 2;
//m_pri = 3; //报错,父类m_pri是私有
}
};
class BossCat : public Cat {
public:
BossCat() {
m_pub = 1; //BossCat的父类中pub 不是私有
m_pro = 2; //BossCat的父类中pro 不是私有
}
};
void testCat() {
BossCat b;
b.m_pub = 1; //BossCat的父类中,pub是公有
//b.m_pro = 2; //报错,BossCat的父类中pro 可能是保护,可能是私有
}
class Dog : protected Animal {//public继承
public:
Dog() {
m_pub = 1;
m_pro = 2;
//m_pri = 3; //报错,父类m_pri是私有
}
};
class PeliceDog : protected Dog {
public:
PeliceDog() {
m_pub = 1; //PeliceDog的父类中pub 不是私有
m_pro = 2; //PeliceDog的父类中pro 不是私有
}
};
void testDog() {
PeliceDog p;
//p.m_pub = 1; //报错,PeliceDog的父类中 pub 可能是保护,可能是私有
//p.m_pro = 2; //报错,PeliceDog的父类中 pro 可能是保护,可能是私有
}
class Pig : private Animal {//public继承
public:
Pig() {
m_pub = 1;
m_pro = 2;
//m_pri = 3; //报错,父类m_pri是私有
}
};
class WildPig : private Pig {
public:
WildPig() {
//m_pub = 1; //报错,WildPig的父类中pub 是私有
//m_pro = 2; //报错,WildPig的父类中pro 是私有
}
};
构造和析构顺序
继承中,构造链里,先构造的后析构
构造子类前会先构造父类
class Animal {
public:
Animal() {
cout << "Animal 构造" << endl;
}
~Animal() {
cout << "Animal 析构" << endl;
}
};
class Cat :public Animal{
public:
Cat() {
cout << "Cat 构造" << endl;
}
~Cat() {
cout << "Cat 析构" << endl;
}
};
class BossCat :public Cat{
public:
BossCat() {
cout << "BossCat 构造" << endl;
}
~BossCat() {
cout << "BossCat 析构" << endl;
}
};
void test() {
//Animal a;
//Cat c;
BossCat bc;
}
int main() {
test();
return 0;
}
同名属性、函数访问
子类和父类有同名属性、函数时,父类属性、函数不会被覆盖。子类想访问父类的属性、函数,加上作用域即可
class Animal {
public:
int m_Data;
Animal() {
m_Data = 12333;
}
void eat(){
cout << "动物吃东西"<<endl;
}
};
class Cat :public Animal {
public:
int m_Data;
Cat() {
m_Data = 33321;
}
void eat(){
Animal::eat(); //可以在此调用父类函数
cout << "猫吃东西"<<endl;
}
};
void Test() {
Cat c;
cout << c.m_Data << endl;
cout << c.Animal::m_Data << endl; //加上Animal::作为作用域
c.eat();
c.Animal::eat(); //加上Animal::作为作用域
cout << &(c.m_Data) << endl;
cout << &(c.Animal::m_Data) << endl; //Animal的m_Data的地址和Cat的m_Data的地址不同
}
int main() {
Test();
return 0;
}
多继承
一个子类可以同时继承多个父类
class Son :public BaseA, public BaseB, public BaseC {
};
继承的不同父类里有同名属性、函数的话,可以用作用域来区分
#include<iostream>
using namespace std;
class BaseA {
public:
int m_A;
int m_Base;
BaseA() :m_A(0), m_Base(998){}
};
class BaseB {
public:
int m_B;
int m_Base;
BaseB() :m_B(1), m_Base(12138) {}
};
class BaseC {
public:
int m_C;
BaseC() :m_C(2) {}
};
class Son :public BaseA, public BaseB, public BaseC {
};
void Test() {
Son s;
s.m_A = 1;
s.m_B = 2;
s.m_C = 3;
//s.m_Base = 22;//报错,BaseA和BaseB里都有m_Base,s.m_Base不明确
s.BaseA::m_Base = 778;//通过作用域明确是哪个m_Base
s.BaseB::m_Base = 998;
}
int main() {
Test();
return 0;
}
浙公网安备 33010602011771号