谈谈c++中继承中的虚函数

c++继 承中的虚函数

c++是一种面向对象的编程语言的一个很明显的体现就是对继承机制的支持,c++中继承分很多种,按不同的分类有不同分类方法,比如可以按照基类的个数分为多继承和单继承,可以按照访问权限分为public继承、protected继承和private继承,按照是否是虚拟继承可以分为virtual继承和non-virtual继承。当然这里的分类标准都是有重叠的部分,比如,non-virtual继承又可以分为单继承和多继承。这里要讨论的是虚函数,因此主要从virtual和non-virtual继承两个方面来展开讨论分析。

1、non-virtual继承

non-virtual继承又有两种情况单继承和多继承。来看一个例子:


 1 class base1
2 {
3 public:
4 virtual void f(){}
5 virtual void h(){}
6 };
7 class base2
8 {
9 public:
10 virtual void g(){}
11 };
12 class derive1:public base1
13 {
14 public:
15 virtual void f(){}
16 virtual void f1(){}
17 }
18 class derive2:public base1,public base2
19 {
20 public:
21 virtual void f(){}
22 virtual void g(){}
23 virtual void g1(){}
24 };

建立四个对象:

base1 b1;

base2 b2;

derive1 d1;

derive2 d2;

学习c++的都知道里面的虚函数表,上面的继承体系中各个类的虚函数表如下:

base1的虚函数表如下:

vptr-->base1::f
base1::h//vptr为指向类的虚函数表的指针,-->表示的意思是指向一个表,后面的内容是表中的内容

base2的虚函数表如下:

vptr-->base2::g //

derive1的虚函数表如下:

vptr-->derive1::f  base1::h derive1::f

derive2的虚函数表如下:

vptr1-->derive2::f base1::h derive2::g1 //base1

vptr2-->derive2::g //base2

在windows开发平台查看虚函数表如下:主机环境为 win7+vs2013(显示的不完全),在调试模式下:

2、virtual继承

虚继承是在多重继承中引入的一种技术,关于虚继承的分析讨论不是本文的重点,不了解的同学可以查看相关的c++书籍,下面要讲的是virtual中的虚函数。

 1 class base1
2 {
3 public:
4 virtual void f(){}
5 };
6 class base2
7 {
8 public:
9 virtual void g(){}
10 };
11 class derive1:virtual public base1
12 {
13 public:
14 virtual void f(){}
15 virtual void f1(){}
16 }
17 class derive2:virtual public base1,virtual public base2
18 {
19 public:
20 virtual void f(){}
21 virtual void g(){}
22 virtual void g1(){}
23 };

通过vs2013查看虚函数表如下:

本文参考了知名技术博主左耳朵耗子在csdn上的博客,

博客地址为:http://blog.csdn.net/haoel/article/details/1948051

欢迎大家来讨论交流,欢迎转载,切勿用于商业用途,版权所有,转载必须注明出处。

谈谈c++中继承中的虚函数,布布扣,bubuko.com

时间: 2024-10-24 09:16:36

谈谈c++中继承中的虚函数的相关文章

【转载】 C++多继承中重写不同基类中相同原型的虚函数

本篇随笔为转载,原文地址:C++多继承中重写不同基类中相同原型的虚函数. 在C++多继承体系当中,在派生类中可以重写不同基类中的虚函数.下面就是一个例子: class CBaseA { public: virtual void TestA(); }; class CBaseB { public: virtual void TestB(); }; class CDerived : public CBaseA, public CBaseB { public: virtual void TestA()

派生类的构造函数和析构函数和多继承中的二义性与虚函数

析构函数主要作用是对数据成员初始化. 1派生类的构造函数 派生类的构造函数定义的一般形式为: 派生类名::派生类名(基类所需形参,本类成员所需形参):基类1(基类1 参数表),基类2(基类2 参数表),···,基类n(基类n 参数表),对象成员1(对象1 参数表),对象成员2(对象2 参数表),···,对象成员m(对象m 参数表){ //本类基本类型数据成员初始化 } 如果使用基类无参构造函数,派生类构造函数形参表中不包含供给基类构造函数的参数.此时,系统会调用基类的默认构造函数.如果使用对象数

含有虚函数菱形的虚拟继承(没有对虚函数进行重写)

在VS2013编程,调试 问题 :  菱形继承会引来,二义性 1.源代码 </pre><pre name="code" class="cpp">#include <iostream> using namespace std; class Base { public: virtual void FunTest() { cout << "Base::FunTest () " << endl;

C++中构造函数能调用虚函数吗?(答案是语法可以,输出错误),但Java里居然可以

环境:XPSP3 VS2005 今天黑总给应聘者出了一个在C++的构造函数中调用虚函数的问题,具体的题目要比标题复杂,大体情况可以看如下的代码: [cpp] view plain copy class Base { public: Base() { Fuction(); } virtual void Fuction() { cout << "Base::Fuction" << endl; } }; class A : public Base { public:

C++中的多态与虚函数的内部实现

1.什么是多态 多态性可以简单概括为“一个接口,多种方法”. 也就是说,向不同的对象发送同一个消息, 不同的对象在接收时会产生不同的行为(即方法).也就是说,每个对象可以用自己的方式去响应共同的消息.所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数.这是一种泛型技术,即用相同的代码实现不同的动作.这体现了面向对象编程的优越性. 多态分为两种: (1)编译时多态:主要通过函数的重载和运算符的重载来实现. (2)运行时多态:主要通过虚函数来实现. 2.几个相关概念 (1)覆盖.重

C++中不能声明为虚函数的有哪些函数

常见的不不能声明为虚函数的有:普通函数(非成员函数):静态成员函数:内联成员函数:构造函数:友元函数. 1.为什么C++不支持普通函数为虚函数? 普通函数(非成员函数)只能被overload,不能被override,声明为虚函数也没有什么意思,因此编译器会在编译时邦定函数. 多态的运行期行为体现在虚函数上,虚函数通过继承方式来体现出多态作用,顶层 函数不属于成员函数,是不能被继承的2.为什么C++不支持构造函数为虚函数? 这个原因很简单,主要是从语义上考虑,所以不支持.因为构造函数本来就是为了明

C++ 对象的内存布局—— 虚继承下的虚函数

C++ 对象的内存布局(下)这篇文章的"单一虚拟继承"和"钻石型虚拟继承"时的类内存布局讲得不太清楚,我有一处疑问,我用的是VS2005.因此记录一下. 类继承图例如以下: 这里:类B被类B1和B2虚拟继承,而B1和B2同一时候被D继承. B1的f().B2的f()覆盖了B的f(): D的f()覆盖了B1的f(),D的f1()覆盖了B1的f1() D的f()覆盖了B2的f(),D的f2()覆盖了B2的f2() 类代码例如以下: class B { public: i

[GeekBand] C++继承关系下虚函数内存分布

本文参考文献:GeekBand课堂内容,授课老师:侯捷 :深度探索C++对象模型(侯捷译) :网络资料,如:http://blog.csdn.net/sanfengshou/article/details/4574604 说明:由于条件限制,仅测试了Windows平台下的VS2013 IDE.其余平台结果可能不同,但原理都类似.建议读者自己在其他平台进行测试. 1.什么是虚函数? 虚函数是类的非静态成员函数,在类中的基本形式如下:virtual 函数返回值类型 虚函数名(形参表) 如:virtu

C++ 链式继承下的虚函数列表

目录 1.虚函数列表的位置 2.虚函数列表的内容 3.链式继承中虚函数列表的内容 ? 注: 虚函数列表 又称为虚表, vtbl , 指向它的指针称为vptr, vs2019中称为__vfptr 操作系统: windows 10 专业版 64位 编译器: Visual Studio 2019 Community ? 1.虚函数列表的位置 结论 编译器一般会保证指向虚函数列表的指针存在于对象实例中最前面的位置 而虚函数列表中的内容, 就是多个函数指针 代码验证: 首先声明一个基类Base和一个派生类