• C++多态、继承的简单分析


    一直以为自己对多态和继承已经比较了解,当遇到虚继承的时候,发现有点犯晕,想不通了,于是在微博上向几个大神请教,很快得到了他们的回复,高兴之情无以言表。之后自己查了一些资料,结合大神的回复,在这里做一下简单的记录。

    我的问题如下:

    为什么虚继承类的sizeof要大些啊,是因为虚继承中,子类有指向父类的指针和指向父类的虚函数表的指针吗,比非虚继承多了这两个指针? @左耳朵耗子 @简悦云风 @GeniusVczh

    @GeniusVczh:调用的时候给的this和函数实际需要的this的指针不一定是一样的,多重继承的时候已经这样了。再加上你还有virtual继承,所以需要很多描述。

    V福尔摩斯 回复 @GeniusVczh:看了B(第三个图中的B)的内存布局,的确有vfptr和vbptr两个指针

    简悦云风:和编译器实现有关。实现上虚继承更象是组合,因为它可以被菱形继承而只有一份,所以加上一个额外指针引用这个对象。没有虚函数时不生成虚表,所以 2 里就是 a 对象加额外指针。3里面 b 有虚表,就再加一个虚表指针。字数不够不吐槽了。

    左耳朵耗子:1) int a :4字节;2)虚函数增加一个虚表指针:4字节。3)虚继承还会增加一个指针:4字节。但是为什么最后会是16个字呢?你是在用VC++吧?看一下我的这篇文章(http://t.cn/a1lMjd 最后一个示例)你会知道VC++的对象布局是有点诡异。G++下应该是正常的。

    看了简悦云风左耳朵耗子两个大神的回复之后,自己觉得还是有点晕,于是看了一下《Effective C++》和《More Effective C++》,在这里做一下记录。

    多态的实现原理

    1:含有虚方法的类都有一个虚函数表

    2:子类的虚方法会覆盖父类对应的虚方法

    3:含有虚方法的类的每个实例都有一个指向虚方法表的指针,如果虚继承的话可能会有多个

    4:根据3中的指针调用虚方法表中对应的虚方法

    多态的实现差不多就是上面几点。面试中经常遇到的就是调用哪个方法的问题,一句话告诉你是怎么调用的:在继承关系中,非虚方法调用指针类型的方法;虚方法调用指针所指的对象类型的方法。非虚方法和默认参数都是静态绑定,在继承关系中只跟指针类型有关,跟指针所指的对象的实际类型无关。还有一点就是非虚方法就像C方法一样,不用太在意,证明非虚方法就像C方法的一个方式就是,用一个空指针调用一个非虚方法,只要这个对象没有用到对象的数据,就不会有任何问题。

    再来看看我发问的哪个图,为什么图3中sizeof(B)=16,于是用VS自带的工具看了一下B的内存布局,如下图:

    查看对象内存布局的VS命令:cl [filename].cpp /d1reportSingleClassLayout[className]

    看到这个图,其实还是不太好理解,int a占4字节,B有自己的虚函数表,虚函数指针占4字节,另外多出一个vfptr和vbptr,那就只能这样理解了:vfptr指向父类的虚函数表,B每多虚继承一个类,就多一个vfptr,不信你可以试试,vbptr指向A,但是每多虚继承一个类,并不多出一个vbptr,这是和解呢?

    @pop_Atry:干嘛不把B到A的偏移量放到虚表里面,何必为每个对象添加一个额外引用?

    @简悦云风:回复@pop_Atry: 1. 性能原因; 2.有的编译器的确是放偏移量的.

    风神一语中的,但如果不按照@pop_Atry,就是我们现在看到的,B变大了。

    妹的,不同的编译器有不同的实现,咋们讨论这个问题有什么意义呢,千万不要把不同编译器编译的代码放到同一个程序中啊,啊哥。

    虚拟继承的出现就是为了解决重复继承中多个间接父类的问题的,保证每个父类都只有一份。

    Effective C++的作者建议尽量避免多继承,如果不能避免也要避免菱形继承,各种莫名其妙的复杂啊。所以说多继承也就算了,还许多(虚多)继承,那就要搞死人了。

    更多了解请看左耳朵耗子的相关博客:http://blog.csdn.net/haoel/article/details/3081385

  • 相关阅读:
    LeetCode-Read N Characters Given Read4 II
    LeetCode-One Edit Distance
    LeetCode-Palindrome Permutation II
    LeetCode- Longest Absolute File Path
    LeetCode-Strobogrammatic Number II
    LeetCode-Strobogrammatic Number
    LeetCode-Flatten 2D Vector
    LeetCode-Shortest Word Distance III
    LeetCode-Shortest Word Distance II
    Cookie/Session
  • 原文地址:https://www.cnblogs.com/hlxs/p/3079302.html
Copyright © 2020-2023  润新知