You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++虚函数场景下两种成员函数调用方式的差异问询

C++虚函数场景下两种成员函数调用方式的差异问询

嘿,我来帮你拆解这两种调用方式的核心差异,结合你给出的代码(先补全你截断的main函数部分)来一步步说清楚~

首先先把完整可运行的代码贴出来:

#include <iostream>

class A {
public: 
    virtual void main() {
        std::cout << "virtual void main of A" << std::endl; 
    }

    int fun() {
        std::cout << "fun function: " << (long long)((void*)&A::main) << std::endl; 
        
        // Member function pointer pointing to A::main
        auto ptr = &A::main; 
        
        // Using 'this' pointer to call the function pointer
        (this->*ptr)();  
        
        // Explicitly calling A::main without virtual mechanism
        this->A::main();
        return 0; 
    }
};

class B : public A {
public:
    void main() override {
        std::cout << "virtual void main of B" << std::endl; 
    }
};

int main() {
    B* b = new B;  
    A* a = b; 
    
    std::cout << "=== Calling via B* ===" << std::endl;
    b->fun();
    std::cout << "\n=== Calling via A* ===" << std::endl;
    a->fun();
    
    delete b;
    return 0;
}

接下来重点分析两种调用方式的区别:

1. (this->*ptr)():触发虚函数动态绑定

  • 这里的ptr是指向A::main的成员函数指针,但因为main是虚函数,这种调用方式会遵循动态绑定规则:它会根据this指针实际指向的对象类型,去对应类的虚函数表里查找并调用正确的函数版本。
  • 比如当this指向B对象时(不管是通过B*还是A*调用fun),这行代码都会输出virtual void main of B。
  • 另外你打印的&A::main的地址,其实对于虚函数来说,这个成员函数指针存储的并不是函数的真实内存地址,而是虚函数表中的偏移量(或者说索引信息),所以你看到的打印值是这个偏移相关的数值,而非函数实际地址。

2. this->A::main():强制静态绑定,绕过虚机制

  • 这里用了显式的类作用域限定符A::,这直接告诉编译器:不管当前对象是什么实际类型,都调用A类定义的main函数,完全绕过了虚函数的动态绑定机制。
  • 所以不管this指向的是A还是B对象,这行代码都会固定输出virtual void main of A,这个调用是在编译期就确定好的,属于静态绑定。

运行结果验证

上面补全的代码运行后会输出:

=== Calling via B* ===
fun function: [某个偏移数值]
virtual void main of B
virtual void main of A

=== Calling via A* ===
fun function: [同一个偏移数值]
virtual void main of B
virtual void main of A

你可以看到,两种指针调用fun时,(this->*ptr)()都调用了B的main,而this->A::main()始终调用A的版本,这就是两种调用方式的核心差异。

备注:内容来源于stack exchange,提问作者Diaos wang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.16 08:29:37