[c++]继承 多态

来源:互联网 发布:域名免费的 编辑:程序博客网 时间:2024/04/28 20:36

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

继承方法:

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;

原因如下图:
这里写图片描述
这里写图片描述

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

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;}

这里写图片描述
论对象模型:
菱形继承:

这里写图片描述

加了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;}

这里写图片描述

菱形虚拟继承:
这里写图片描述

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

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

这里写图片描述

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

3 0