c++ - 什么时候静态调用虚函数?

标签 c++ performance pointers polymorphism virtual-functions

直接从派生类指针调用虚函数与​​从指向同一派生类的基类指针调用虚函数有什么性能差异?

在派生指针的情况下,调用是statically bound吗? ,还是动态绑定(bind)?我认为它将被动态绑定(bind),因为不能保证派生指针实际上不指向进一步的派生类。如果我直接通过值(而不是通过指针或引用)获得派生类,情况会改变吗?所以这 3 种情况:

  1. 派生的基指针
  2. 派生指针派生
  3. 按值(value)推导

我很关心性能,因为代码将在微 Controller 上运行。

演示代码

struct Base {
    // virtual destructor left out for brevity
    virtual void method() = 0;
};

struct Derived : public Base {
    // implementation here
    void method() {
    }
}

// ... in source file
// call virtual method from base class pointer, guaranteed vtable lookup
Base* base = new Derived;
base->method();

// call virtual method from derived class pointer, any difference?
Derived* derived = new Derived;
derived->method();

// call virtual method from derived class value
Derived derivedValue;
derived.method();

最佳答案

  • 理论上,唯一有区别的 C++ 语法是使用限定 成员名称的成员函数调用。根据您的类定义,

    derived->Derived::method();
    

    此调用忽略对象的动态类型并直接转到 Derived::method(),即它是静态绑定(bind)的。这仅适用于调用类本身或其祖先类之一中声明的方法。

    其他一切都是常规的虚函数调用,根据调用中使用的对象的动态类型进行解析,即动态绑定(bind)。

  • 在实践中,编译器将努力优化代码,并在对象的动态类型在编译时已知的上下文中用静态绑定(bind)调用替换动态绑定(bind)调用。例如

    Derived derivedValue;
    derivedValue.method();
    

    通常会在几乎每个现代编译器中产生静态绑定(bind)调用,即使语言规范没有为这种情况提供任何特殊处理。

    此外,直接从构造函数和析构函数进行的虚方法调用通常会编译为静态绑定(bind)调用。

    当然,智能编译器可能能够在更多种类的上下文中静态绑定(bind)调用。例如,两者

    Base* base = new Derived;
    base->method();
    

    Derived* derived = new Derived;
    derived->method();
    

    可以被编译器视为很容易允许静态绑定(bind)调用的微不足道的情况。

关于c++ - 什么时候静态调用虚函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43252822/

相关文章:

c - char* x 和 char* x[80] 的区别?

c++ fork,没有等待,defuncts execl

c++ - 如何防止 C++ 模板的特化?

sql - 如何优化这个 AspNetIdenty/Entity Framework 生成的查询?

c++ - 是 T Min(T, T);总是比 const T& Min(const T&, const T&) 好;如果 sizeof(T) <= sizeof(void*)?

C++ 内存泄漏 new 运算符

c++ - 如何使用 'new' 而不是 'malloc' 动态分配二维数组?

c++ - 关于重新定义成员函数的小问题

c++在后台运行system(),目录路径中有空格,+输出到文本文件

java - Java 中的 Integer() 有多大?