前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++多态

C++多态

作者头像
用户2929716
发布2018-08-23 13:15:27
4280
发布2018-08-23 13:15:27
举报
文章被收录于专栏:流媒体流媒体

多态原理

当类存在虚函数时,编译器会为该类维护一个表,这个表就是虚函数表(vtbl),里面存放了该类虚函数的函数指针。在构造类的时候增加一个虚表指针(vptr)指向对应的虚函数表。在类执行成员函数时候,先判断该函数是否是虚函数,如果不是虚函数则直接执行对应的方法,如果是虚函数则从虚函数表中找到应该调用的函数。

  • vptr的初始化是在类的构造时候完成。而在进行父类构造的时候,vptr指向的是父类vtbl。执行完子类的构造函数后,vptr在指向子类的btbl。
  • 父类指针(引用)指向子类进行多态调用时候,编译器并不关系是子类还是父类,而是通过vptr指向的btbl来找到对应的函数指针,并调用函数。
  • vtbl由编译器来维护

重载、覆盖、隐藏的区别和执行方式

4.1成员函数被重载的特征 (1)相同的范围(在同一个类中); (2)函数名字相同; (3)参数不同; (4)virtual 关键字可有可无。 4.2“覆盖”是指派生类函数覆盖基类函数,特征是: (1)不同的范围(分别位于派生类与基类); (2)函数名字相同; (3)参数相同; (4)基类函数必须有virtual 关键字。 4.3“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,特征是:

(1)如果派生类的函数与基类的函数同名,但是参数不同,此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。 (2)如果派生类的函数与基类的函数同名,但是参数相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。

小结:说白了就是如果派生类和基类的函数名和参数都相同,属于覆盖,这是可以理解的吧,完全一样当然要覆盖了;如果只是函数名相同,参数并不相同,则属于隐藏。

示例

代码语言:javascript
复制
class Parent {
public:
    int x;

    Parent(int x) {
        this->x = x;
    }

     void print() {
        cout << "Parent " << x << endl;
    }
};

class Children : public Parent {
public:

    Children(int x) : Parent(x) {

    }

     void print() {
        cout << "Children " << x << endl;
    }
};

int main() {
    Parent *parent = NULL;
    Parent p(1);
    Children c(10);
    parent = &p;
    parent->print();
    parent = &c;
    parent->print();
}

测试一运行结果,发现虽然父类指针或引用指向了子类,但是在调用方法时候还是调用的父类的方法

代码语言:javascript
复制
Parent 1
Parent 10

测试二,对print方法加上virtual关键字,这时才体现出多态

代码语言:javascript
复制
Parent 1
Children 10
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.08.17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 多态原理
  • 重载、覆盖、隐藏的区别和执行方式
  • 示例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档