[c++]继承 多态

继承: 是除了基类的构造函数 ,析构函数 全部继承(私有 也可继承 但不可直接访问)

继承方法:

public: is-a关系
base private 不可访问
public protected 不变

protected:
base private protected 都不可访问
public 变为 protected

注:protected 不能在类外访问,可在类内访问 基类成员不想在类外被直接访问但在派生类中可访问

private:
base private 不能访问
protected public 都变成private

注:类的默认访问权限:private
结构体的访问默认权限:public

关于基类构造和析构函数的调用:

class A :public B,public C//调用构造函数顺序:B(),C(),A()
{
A()
:C(0)
,B(10)
{}//和该顺序无关
}//构造函数调用顺序:B(),C(),A()
先看继承列表,再看派生类内的内容
class A :public B,C(私有的)

不同情况下编译器会调用构造函数:
1.基类有缺省构造函数,派生类无构造函数编译器会自动合成派生类的构造函数
2.基类和派生类都没构造,编译器不回调用默认的构造
3.私有成员中有类对象的存在,并且该类对象存在缺省的构造函数
注:
基类如果没有缺省的构造函数,派生类中必须显示给出默认参数列表
基类没定义构造,派生类也不用定义,都调用默认的

同名隐藏:

如果基类中存在同名成员,则先调用派生类中的,调用基类的同名成员时加作用域。派生类里没有该方法,才调用基类的。(子类成员会屏蔽父类成员)只有加了基类的作用域才会调用基类的同名成员。
继承体系中最好不定义同名成员。
注:
派生类和基类不在同一作用域,故不能构成重载

赋值兼容规则:

必须在public关系继承下:
·派生类的对象可以赋值给基类对象。

Base b; Derive d; b = d;

·派生类的对象可以初始化基类的引用。

Deriver d; Base &b = d;

·派生类对象的地址可以赋给指向基类的指针。

Deriver *d; Base* b = &d;

原因如下图:

[c++]继承 多态_第1张图片

友元与继承:友元关系不能继承,如果要继承基类和派生类中都必须声明

friend void Display(Base b)
{
     cout<<b._pri<<endl;//(b的私有成员)
}

继承与静态成员
子类可以继承静态成员

class A
{};
sizeof(A) = 1;
大小为1的原因:占位符,假设有一个空类A我们规定他们的大小为0并且0地址对齐,紧接着有非空类B,从0地址开始看不到A类。

菱形继承:

class Base
{
    int _pir;
};
class Base1: public Base
{
    int _pir; 
};
class Base2: public Base
{
    int _pir; 
};
class Derive :public Base1,public Base2
{
    int _dpir;
};
int main()
{
    Base b;
    Base1 b1;
    Base2 b2;
    Derive d;
    cout<<sizeof(b)<<endl;
    cout<<sizeof(b1)<<endl;
    cout<<sizeof(b2)<<endl;
    cout<<sizeof(d)<<endl;

    return 0;
}

[c++]继承 多态_第2张图片
论对象模型:
菱形继承:

[c++]继承 多态_第3张图片

加了virtual后

class Base
{
    int _pir;
};
class Base1: virtual public Base
{
    int _pir; 
};
class Base2: virtual public Base
{
    int _pir; 
};
class Derive : public Base1,public Base2
{
    int _dpir;
};
int main()
{
    Base b;
    Base1 b1;
    Base2 b2;
    Derive d;
    cout<<sizeof(b)<<endl;
    cout<<sizeof(b1)<<endl;
    cout<<sizeof(b2)<<endl;
    cout<<sizeof(d)<<endl;

    return 0;
}

[c++]继承 多态_第4张图片

菱形虚拟继承:
[c++]继承 多态_第5张图片

上面图中提到的虚表见下面解释:如果在类内定义了虚函数或纯虚类就需要用到虚表

多态:
多态分为编译时多态和运行时多态:
函数重载,模版是静态类型多态,编译期间确定
虚函数是运行时多态

多态的实现方式:
父类的指针或引用

你可能感兴趣的:(C++,继承)