继承关系和复合关系
- 继承关系:“是”关系,A派生B,对象B是B,也是A
class Human{ int age; char name[20]; } class Women:public Human{ //Women继承自Human char cup; }
表述出来便是:女人是女人,女人也是人。
- 复合关系:"有” 关系,A对象是B对象的组成成分或固有属性
class point { double x,y
friend class circlie;
}; class circlie{ float radius; point p; //圆的对象里有一个圆心 };
表述为:圆和点中,在圆中都有一个圆心。(最好声明为fridend)。
小结:在复合关系和继承关系的选择时,要看是否选择合理,比如如果使用继承关系来表示圆和点的关系,那么表述出来:圆是圆,圆是点,显然不符合逻辑。故此时应采用复合关系。
例子:如果要开发一个小区业主管理的宠物狗的管理系统,那么应该怎样设计?
人中有狗 狗中有人---》错! 循环定义,Cdogs 和 Cmaster 对象都含有彼此,死循环!
狗中有人 -->健壮性差,两狗一主人,主人修改麻烦
人中有狗-->人中的狗不是人的固有属性,对狗难操作需间接通过主人进行
人和狗中指针互指。
基类派生类含有同名成员的情况
相同对象、相同函数? 引用哪一个??
派生来不能访问基类的private
优先引用派生类中的成员。
base::x 引用的是基类
空间存储情况:
存储空间中基类在派生类的前面
tip:一般不定义同名成员的变量名,同名函数允许
访问访问说明符
private:
基类的成员函数
基类的友元函数
public
基类的成员、友元函数
派生类的成员、友元函数
其他的函数
protected
基类的成员、友员函数
派生类的成员函数可以访问当前对象的基类保护对象成员。
当没有选择访问控制符时,默认为private
类中再生成一个自己的对象?????
派生类的构造函数
派生包含基类对象,先执行基类构造函数,再执行派生类构造函数
形式:
构造函数名(形参表):基类名(基类构造函数实参表){}
在派生类的构造函数中告诉基类的构造函数进行初始化。
正确的派生类构造函数:
1.调用基类的构造函数
2.初始化派生类对象中丛基类继承的成员
即先执行基类的构造函数,后执行派生类的构造函数
调用基类构造函数的两种方式:
- 隐式方式:
- 派生类的构造函数 自动调用基类的默认构造函数
- 显式方式:
- 派生类的构造函数中->基类的构造函数提供参数
- 派生类中的形参具体是写在基类里面的
- derived::derived(arg_aderived-list):base(arg_base-list)
- 同样地,析构函数正好相反,派生类析构函数执行后,再去执行基类的析构函数
包含成员对象的派生类的构造函数:(即类中实例化其他类的对象)
此时需要对派生类的构造函数不止需要对其基类的进行初始化而且需要对其成员对象进行初始化
--->调用基类的构造函数-->调用成员对象类的构造函数
- 同样,析构函数正好相反
public继承赋值兼容规则
- b = d 派生类赋值给基类
- base & br = d; 派生类对象可以初始化基类引用
- base * pb = & d; 派生类的地址可以赋值给一个基类指针,可以理解为:这个指针指向派生类包含的对象
仅限public继承
直接基类、间接基类
派生类只需列出它的直接基类,列出直接基类的构造函数
https://www.bilibili.com/video/av10046030/?p=34