前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >c++继承 基类 派生类 虚函数

c++继承 基类 派生类 虚函数

作者头像
用户7886150
修改2021-02-03 10:40:32
1.1K0
修改2021-02-03 10:40:32
举报
文章被收录于专栏:bit哲学院

参考链接: C++继承

继承 

  类和类的关系有组合、继承和代理。继承的本质就是代码复用。子类继承父类中的一些东西,父类也称为基类,子类也称为派生类。派生类继承了基类除构造函数以外的所有成员。 

继承的方式 

  继承方式有public(公有继承)、private(私有继承)和protected(保护继承)。基类中不同访问限定符下(public、protected、private)的成员以不同的继承方式继承,在派生类中的访问限定也不同,具体如下: 

基类的布局优先于派生类 

#include<iostream>

class Base

{

 public:

    Base(int a)

       :ma(a)

    {

    }

public:

    int ma;

};

class Derive :public Base

{

public:

    Derive(int b)

       :mb(b), Base(b)

    {

    }

public:

    int mb;

};

int main()

{

    Derive(20);

    return 0;

  我们可以在开发人员命令提示符窗口中进入当前源文件的目录,使用cl ConsoleApplication5.cpp /d1reportSingleClassLayoutDerive来查看派生类Derive的布局如下:  由图可见,基类的布局优先级高于派生类。那么派生对象的构造方式是怎么样的呢? 1.调用基类的构造函数 2.调用派生类的构造函数 派生类的析构可想而知: 1.调用派生类的析构函数 2.调用基类的析构函数 

虚函数 

如下程序: 

class Base

{

public:

    Base(int a)

       :ma(a)

    {}

    virtual void Show()

    {

       std::cout << "Base:Show  ma=" << ma << std::endl;

    }

protected:

    int ma;

};

class Derive :public Base

{

public:

    Derive(int b)

       :mb(b), Base(b)

    {

    }

    void Show()

    {

       std::cout << "Derive:Show  mb=" << mb << std::endl;

    }

protected:

    int mb;

};

int main()

{

    std::cout << "sizeof(Base):" << sizeof(Base) << std::endl;

    std::cout << "sizeof(Derive):" << sizeof(Derive) << std::endl;

    Base* pb=new Derive(20);

    std::cout << typeid(pb).name()  << std::endl;

    std::cout << typeid(*pb).name() << std::endl;

    pb->Show();

    return 0;

运行结果如下:    上面结果说明一个基类的指针是可以指向其派生类对象的。基类中含有虚函数,那么基类布局中存在一个虚函数指针,指向虚函数表;且其派生类中与其同名同参的函数不需要加virtual也是虚函数。此时基类和派生类的布局如下: 

   vfptr的指针大小为4(32位机器)。因此基类字节数为8,派生类为12。vfptr指针指向的vftable(虚函数表)中,&Base_meta中存放了RTTI信息(运行时类型信息),也就是class Base,0表示偏移,&Base::Show表示虚函数的入口地址。typeid()可以动态获取类型。   main函数中,生成了一个派生类对象。pb是一个指针类型,它的类型只和定义点有关,因此打印出来pb的类型为class Base类型;而pb是一个自定义类型,动态获取类型时,先通过指针pb解引用找到派生类对象,通过vfptr找到vftable,&Derive_meta中存放了派生类的RTTI信息,其中存放的是class Derive,因此*pb的类型是class Derive。   pb指针调用Show()函数时,发生了动多态。首先通过指针所指向的对象找到vfptr,再找到vftable,获取到Show函数的入口地址,此时 &Derive::Show中存放的是派生类的虚函数入口地址,因此调用的是派生类中的Show()函数。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档