读书人

多重继承对非虚函数是否也会造成额外开

发布时间: 2012-02-28 13:06:35 作者: rapoo

多重继承对非虚函数是否也会造成额外开销?
因为只要有了多重继承,那么类型转换就会有偏移地址的问题。

书里说标准没有规定多个基类如何排序。也就是说尽管基类通常按照声明的顺序排序,但是我不能指望编译器一定会这么做,因此就无法保证哪些类型转换会需要偏移地址,哪些不需要。

因此,从理论上来讲,我就应该认为一旦出现多重继承,那么所有原先在单继承中没有额外开销的方法都可能需要额外开销了。

例如:
某类BASE的方法BASE::method()被编译成:
method_BASE( BASE *b );
其派生类DERIVED的对象derived调用的时候就要:
如果是单继承则可以直接传递自己
method_BASE( &derived );

但是一旦DERIVED类又继承了另外一个类,同样在调用这个方法的时候就不能保证转换是正确的,因此需要寻找基类的偏移地址再传入参数,因此导致了额外的开销。

我这么理解是否正确?

[解决办法]
编译时完成,无额外开销
[解决办法]
最多也就做一次加法以计算指针偏移。
[解决办法]
调用虚函数时使用的函数地址需要在运行时确定。这个计算过程可以参考《深度探索C++对象模型》。实际开销也不大。
[解决办法]
虚函数最大的开销是没有办法内联,即使只有一条指令
[解决办法]
没多余开销,编译器知道类排放顺序,当然也知道偏移量。
[解决办法]
只有虚拟函数的地址放在虚表里面需要间接引用
其他非虚函数是不需要这个开销的
[解决办法]
非虚函数的址一般编译时就可以确定...所以不太会造成性能上的开销...
[解决办法]
那是不是一些虚函数的调用也可以在编译时确定?
--------------------------------------------
正确,明确加上类限定符或直接用对象调用的虚函数可以在编译时确定,合适的话也会进行内联。
[解决办法]
楼主要是对多继承感兴趣可以看看《深度探索C++对象模型》。
[解决办法]
非虚函数的入口地址都是编译时候确定的,没有额外的开销吧
[解决办法]
建议看《深度探索C++对象模型》
[解决办法]
而且对象是运行时分配的,对象地址是运行时决定的,所以应该不能在编译时就确定吧?
---------------
也不能完全的认为对象的地址是运行时决定的,对于静态分配的对象和栈上分配的对象,它们相对于基址的偏移量是在编译就可以确定的.只有动态分配的对象具体的值是在运行时确定的.
由于多继承造成的this指针修正(或者偏移)却在编译阶段就可以确定下来的.你通过观察编译后的汇编代码(不是运行时Debug状态的反汇编),你会发现,this指针的偏移量是常数.

[解决办法]
如果你给函数传基类指针,编译器会对传入的指针做偏移。引用也类似。
这一个偏移运算还是有一点点运行开销的。

读书人网 >C++

热点推荐