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日

posted @ 2024-04-08 16:28  千松  阅读(47)  评论(0)    收藏  举报