C++引用与非引用调用虚函数的区别
C++引用与非引用调用虚函数的区别
根据C++的规定,虚函数只有通过指针或者引用的方式调用时才会体现出多态性,而普通的值对象调用虚函数则只会调用该类自身的函数。
这一特性可以在以下代码中体现:
#include <cstdio>
class Base
{
public:
virtual void fun() { puts("Base"); }
};
class Derived : public Base
{
public:
virtual void fun() { puts("Derived"); }
};
int main()
{
Derived d;
Base b1 = d;
Base &b2 = d;
b1.fun();
b2.fun();
return 0;
}
输出的结果为
Base
Derived
可以看出,值对象b1即使是从派生类对象d赋值,其调用的函数也是自身的Base::fun()。而引用(或指针)对象b2在引用d之后成功调用了派生类的虚函数Derived::fun()。
比较一下二者汇编代码的区别:
20 b1.fun();
0x000000000040157b <+43>: lea rax,[rbp-0x18]
0x000000000040157f <+47>: mov rcx,rax
0x0000000000401582 <+50>: call 0x402c50 <Base::fun()>
21 b2.fun();
0x0000000000401587 <+55>: mov rax,QWORD PTR [rbp-0x8]
0x000000000040158b <+59>: mov rax,QWORD PTR [rax]
0x000000000040158e <+62>: mov rax,QWORD PTR [rax]
0x0000000000401591 <+65>: mov rdx,QWORD PTR [rbp-0x8]
0x0000000000401595 <+69>: mov rcx,rdx
0x0000000000401598 <+72>: call rax
可以看出,b1.fun()会直接调用Base::fun(),没有访问虚函数表的操作,故不存在多态。而b2.fun()则会先查询虚函数表,再调用表中对应的函数来实现多态。
本文发布于2024年4月8日
最后编辑于2024年4月8日

浙公网安备 33010602011771号