虚函数

C++用虚函数实现运行时多态,虚函数的实现是由两个部分组成的,虚函数指针与虚函数表。

虚函数指针(vptr)是指向虚函数表的指针,在一个被实例化的对象中,它总是被存放在该对象的地址首位。而虚函数表(vtbl)用于保存类包含的虚函数指针列表:

class Base {
public:
virtual void f() {
std::cout << "Base::f()" << std::endl;
} private:
int n;
}; int main() {
Base* base = new Base; return 0;
}

单继承下虚函数的内存布局

在单继承中,子类覆盖父类的虚函数,其实只需要在子类对应的虚函数表中覆盖对应的虚函数指针即可:

class Base {
public:
virtual void f() {
std::cout << "Base::f()" << std::endl;
} private:
int n;
}; class Derived : public Base {
public:
void f() override {
std::cout << "Derived::f()" << std::endl;
} virtual void k() {
std::cout << "Derived::k()" << std::endl;
} private:
int h;
}; int main() {
Derived* derived= new Derived; return 0;
}

多继承下虚函数的内存布局

class Base1 {
public:
virtual void f() {
std::cout << "Base1::f()" << std::endl;
} private:
int n;
}; class Base2 {
public:
virtual void g() {
std::cout << "Base2::g()" << std::endl;
} private:
int m;
}; class Derived : public Base1, public Base2 {
public:
void f() override {
std::cout << "Derived::f()" << std::endl;
} void g() override {
std::cout << "Derived::g()" << std::endl;
} virtual void k() {
std::cout << "Derived::k()" << std::endl;
} private:
int h;
}; int main() {
Derived* derived= new Derived; return 0;
}

C++虚函数与多继承的更多相关文章

  1. c++内存分布之虚函数(多继承)

    系列 c++内存分布之虚函数(单一继承) c++内存分布之虚函数(多继承) [本文] 结论 1.虚函数表指针 和 虚函数表 1.1 影响虚函数表指针个数的因素只和派生类的父类个数有关.多一个父类,派生 ...

  2. c++内存分布之虚函数(单一继承)

    系列 c++内存分布之虚函数(单一继承) [本文] c++内存分布之虚函数(多继承) 结论 1.虚函数表指针 和 虚函数表 1.1 影响虚函数表指针个数的因素只和派生类的父类个数有关.多一个父类,派生 ...

  3. Visual C++ 8.0对象布局的奥秘:虚函数、多继承、虚拟继承(VC直接输出内存布局)

    原文:VC8_Object_Layout_Secret.html 哈哈,从M$ Visual C++ Team的Andy Rich那里又偷学到一招:VC8的隐含编译项/d1reportSingleCl ...

  4. VC++对象布局的奥秘:虚函数、多继承、虚拟继承

    哈哈,从M$ Visual C++ Team的Andy Rich那里又偷学到一招:VC8的隐含编译项/d1reportSingleClassLayout和/d1reportAllClassLayout ...

  5. 虚函数重载(overwrite) 继承覆盖问题

    引言 类接口需要添加默认参数,以适应不同情况调用, 但是clang-tidy 不允许在接口上设置默认参数,ps: 可能担心继承类里接口重新设置新默认参数而导致误用的情况 #include <st ...

  6. C++逆向分析----虚函数与多层继承

    虚函数 C++通过关键字virtual来将函数声明为一个虚函数.当一个类包含虚函数后编译器就会给类的实例对象增加一个虚表指针,所谓的虚表指针就是指向虚表的指针.虚表就是一张地址表,它包含了这个类中所有 ...

  7. C++中的继承与虚函数各种概念

    虚继承与一般继承 虚继承和一般的继承不同,一般的继承,在目前大多数的C++编译器实现的对象模型中,派生类对象会直接包含基类对象的字段.而虚继承的情况,派生类对象不会直接包含基类对象的字段,而是通过一个 ...

  8. C++ 派生类函数重载与虚函数继承详解

    目录 一.作用域与名字查找 1.作用域的嵌套 2.在编译时进行名字查找 3.名字冲突与继承 4.通过作用域运算符来使用隐藏的成员 二.同名函数隐藏与虚函数覆盖 1.几种必须区分的情况 2.一个更复杂的 ...

  9. 【转】 C++的精髓——虚函数

    虚函数为了重载和多态的需要,在基类中是由定义的,即便定义是空,所以子类中可以重写也可以不写基类中的函数! 纯虚函数在基类中是没有定义的,必须在子类中加以实现,很像java中的接口函数! 虚函数 引入原 ...

随机推荐

  1. java 检查进程是否存在

    以nginx进程为例子 private final static String NAME_STRING = "nginx.exe"; //传入进程名称processName pub ...

  2. Git 实用操作:撤销 Commit 提交

    有的时候,改完代码提交 commit 后发现写得实在太烂了,连自己的都看不下去,与其修改它还不如丢弃重写.怎么操作呢? 使用 reset 撤销 如果是最近提交的 commit 要丢弃重写可以用 res ...

  3. nginx系列(七)静态文件合并combo

    根据雅虎性能优化准则,可以将大量的小型JS文件进行合并,用来提高WEB服务器的性能.下面就是笔者的一个实践. 目前必须安装在1.4.+才可以 官方:http://wiki.nginx.org/Http ...

  4. 接口自动化---简单的数据驱动框架ATP(基于excel)

    数据驱动测试:根据数据进行测试.将用例写入excel文件,用代码读取文件中的数据,从而实现自动化测试. 自动化框架实现步骤: 1.获取用例 2.调用接口 3.校验结果 4.发送测试报告 5.异常处理 ...

  5. 我是怎样通过个人项目成长为高级 JavaScript 开发者的

    大道理都是能用三两句话说清的 . 在我开发人员的职业生涯中,最好的决定之一就是不再满足于只做工具的使用者. 我决定创建我自己的工具,并不是为了卖钱,而是要了解这些技术的实际工作方式,并提升我的技术技能 ...

  6. 修改mysql、sqlserver数据库默认用户,不允许为root、sa等

    1.mysql cmd进入dos命令,输入mysql -u root -P 1202 -h localhost -p敲回车输入密码 use mysql; 修改用户名root为其他用户 update u ...

  7. js 去掉字符串最后一个逗号:笑死我了

    今天突然遇到js 去掉字符串最后一个逗号的问题,本想偷懒搜个代码吧,没想到看到百度的第一条记录是这么一篇文章. 网易博客: http://blog.163.com/li_crane/blog/stat ...

  8. (专题一)07 matlab中字符串的表示

    matlab中,字符串使用单引号括起来的字符序列 >>xm='Central South University' >>xm(1:3) ans= Cen 截取1--3这三个字符, ...

  9. netty之pipeline

    转载自https://blog.csdn.net/zxhoo/article/details/17264263 Netty4学习笔记(1)-- ChannelPipeline Netty4Netty是 ...

  10. Mybatis的几种传参方式,你了解吗?

    持续原创输出,点击上方蓝字关注我 目录 前言 单个参数 多个参数 使用索引[不推荐] 使用@Param 使用Map POJO[推荐] List传参 数组传参 总结 前言 前几天恰好面试一个应届生,问了 ...