继承的概念
1 2 3 4 5 6 7 8 9 10 class Base {}; class Derive :public Base{}; class Derive2 :protected Base {}; class Derive3 :private Base{};
多继承
如果省略继承方式,默认为private
1 2 3 class <派生类名>:<继承方式1 ><基类名1 >,<继承方式2 ><基类名2 >,....{ };
private 和 protected 区别:类继承,private无法被访问 protected可以被访问。
继承的时候,私有变量是占内存空间的,但是没办法访问。。。
继承中的访问控制
一般来说,尽量设计类的成员变量为private,如果需要访问这些成员变量,应该提供setter以及getter函数。
继承中的构造函数
1 2 3 4 5 6 7 8 9 10 11 12 13 class object { }; class mapObject :public object{ }; class actObject :public mapObject{ };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 #include <iostream> class object { public : int x; int y; object () { std::cout << "object was created\n" ; } object (const object& obj) { std::cout << "object was created by copy\n" ; } }; class mapObject :public object{ public : int mapId; mapObject () { std::cout << " mapObject was created\n" ; } mapObject (const mapObject& obj) { std::cout << " mapObject was created by copy\n" ; } mapObject (int id) :mapId{ id } { } }; class actObject :public mapObject{ public : int damage; actObject ():mapObject{100 },damage{100 } { mapId = 3939 ; std::cout << " actObject was created\n" ; } actObject (const actObject& obj):mapObject{obj} { std::cout << "actObject" << std::endl; } }; int main () { actObject obj{}; std::cout << "------------" << std::endl; actObject obj2 = obj; }
继承构造函数
允许派生类从基类继承构造函数。这意味着派生类可以使用基类的构造函数来初始化从基类继承来的数据成员,而不需要在派生类中重新定义类似的构造函数(默认构造函数和副本构造函数无法继承)
语法:using <基类名称>::<基类名称>;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 #include <iostream> class object { public : int x; int y; object () { std::cout << "object was created\n" ; } object (const object& obj) { std::cout << "object was created by copy\n" ; } }; class mapObject :public object{ public : int mapId; mapObject () { std::cout << " mapObject was created\n" ; } mapObject (const mapObject& obj) { std::cout << " mapObject was created by copy\n" ; } mapObject (int id) :mapId{ id } { std::cout << id; } mapObject (int id, int id2) :mapId{ id } { std::cout << id; } }; class actObject :public mapObject{ public : using mapObject::mapObject; int damage; actObject ():mapObject{100 },damage{100 } { mapId = 3939 ; std::cout << " actObject was created\n" ; } actObject (const actObject& obj):mapObject{obj} { std::cout << "actObject" << std::endl; } }; int main () { actObject obj{200 }; actObject objx{ 200 ,300 }; std::cout << "------------" << std::endl; actObject obj2 = obj; }
继承中的析构函数与重名问题
构造的时候由基类开始构造的,析构的时候恰恰相反,先析构派生类的
继承中的成员变量名称重复的问题
1️⃣ 函数名相同,参数不同
using 基类::函数名
不会出错,有个作用域的问题,不存在变量名重复的问题,访问的时候 使用作用域的符号 object::x
1 2 3 mapObject MAP; MAP.x = 2500 ; MAP.object::x = 3500 ;
2️⃣ 函数名相同,参数相同
基类::函数名
函数存在一个重载的问题,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 using object::showX;int ShowX (int x) { } using object::showX;int ShowX (int x) { } int ShowX (int x) { } mapObject MAP: MAP.ShowX (1500 ); MAP.object::ShowX (2500 ); actObject obj; obj.ShowX ("222" ); obj.mapObject::ShowX (33 ); obj.mapObject::object::ShowX (44 ); obj.object::ShowX (55 );
多重继承问题
多重继承带来的重复继承的问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 #include <iostream> class Wolf { public : void bite () { std::cout << "Wolf Bite!\n" ; } void eat () { std::cout << "Wolf eat!\n" ; } }; class Man { public : void eat () { std::cout << "Man eat!\n" ; } }; class WolfMan :public Wolf, public Man{ public : void Change () { IsWolf = !IsWolf; } void eat () { if (IsWolf) Wolf::eat (); else Man::eat (); } private : bool IsWolf = false ; }; int main () { WolfMan Jack; Jack.bite (); Jack.eat (); Jack.Change (); Jack.eat (); }
派生类之间的内存并不是重叠的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class MoveObject { public : int x; int y; }; int main () { WolfMan Jack; Jack.bite (); Jack.Wolf::x = 250 ; Jack.Wolf::y = 250 ; std::cout << Jack.Wolf::x << std::endl; std::cout << Jack.Man::x << std::endl; }
虚基类 ,如果发现已经继承一次了,下次就不会再继承的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 int main () { WolfMan Jack; Jack.bite (); Jack.Wolf::x = 250 ; std::cout << Jack.Wolf::x << std::endl; std::cout << Jack.x << std::endl; std::cout << Jack.Man::x << std::endl; }
从内存的角度来理解继承