继承:
1、子类拥有父类的所有成员变量(属性)和成员函数(方法)
2、子类是一种特殊的父类
3、子类对象可以当父类对象使用
4、子类可以拥有父类没有的方法和属性
继承方式一般都按照public继承;
单个类的访问(属性和方法)控制:
public:类内,类外均可用
private:类内
protected:类内,继承的子类内部
派生类的访问控制:
继承方式:public继承,子类对父类的访问属性不变
protected:父类public变成子类内部的protected
private:全部转化为子类内部的private属性
赋值兼容性原则:
1、父类指针或引用 指向父类或子类(多态)
2、可以用子类 初始化 父类(子类是一种特殊的父类)
继承中构造函数析构函数的调用规则:
构造:先父类后子类
析构:先子类后父类
在子类中使用构造函数初始化列表,先初始化父类的成员,后初始化自己成员。析构逆序。
child(int a, int b, int c):parent(a, b)
{
this->c = c;
}
继承和组合(子类中定义了父类的对象)的混合,构造析构调用方法
子类构造函数不仅需要初始化自己的成员变量还要初始化父类的成员变量,
此时,需要使用构造函数初始化列表,调用父类的构造函数来初始化父类的成员变量
构造函数初始化列表:组合,继承中使用
组合:子类中有父类的对象
继承:在子类构造函数中初始化父类成员
调用顺序,先调用父类构造函数,如果父类还有父类(老祖宗),
就先从祖先开始,依次往下调用,直到子类时,先调用子类中组合对象构造函数再调用子类自己构造函数。
析构时顺序相反。
继承中同名成员变量处理方法:
1、子类成员变量 与 父类成员变量同名时 子类依然从父类继承同名成员变量
2、通过 域作用符 区别子类和父类的同名成员变量(子类中使用父类的域作用符)
3、同名成员存储在内存中不同位置。
child.b = 1; //默认使用子类自己的b
child.parent::b = 2; //子类调用父类的b(使用了父类的域作用符)
派生类中的static关键字
父类中的static成员,满足派生类的访问控制
静态成员变量 类外定义初始化,提醒编译器分配内存
类中不声明,默认为私有。构造函数声明为一般公有(单例除外)(结构体中默认为公有)
继承是二义性:A派生B和C两个类;D继承自B和C,D中对象调用A的成员b时不知道是通过B还是通过C来调用。
解决这个问题,需要采用虚继承。
class B:vitual class A
{};
class C:vitual class A
{};
class D:public B, public C
{};
但B和C都有成员变量k时,D的对象无法直接访问k,虚继承也无法解决,但可以使用父类作用域去访问。