为什么编译器会使用下面的' datum::rotate() '的虚调用?

Why would the compiler use a virtual call for `datum::rotate()` below?

本文关键字:rotate 调用 编译器 datum 为什么      更新时间:2023-10-16

在S. Lippman的"Inside the c++ Object Module"的第26页,您会发现以下代码片段:

void rotate(
X datum,
const X *pointer,
const X &reference )
{
    // cannot determine until run-time
    // actual instance of rotate() invoked
    (*pointer).rotate();
    reference.rotate();
    // always invokes X::rotate()
    datum.rotate();
}
main() {
    Z z; // a subtype of X
    rotate( z, &z, z );
    return 0;
}

和本段:

The two invocations through pointer and reference are resolved dynamically. In this example, they both invoke Z::rotate(). The invocation through datum may or may not be invoked through the virtual mechanism; however, it will always invoke X::rotate().

当然,datum.rotate()总是通过静态调用来调用的。为什么编译器会在这里使用虚调用?

编译器可能会选择使用虚调用,即使这样做是不必要的。标准并没有说编译器"必须"将其转换为静态调用。只要调用了"正确的"函数,编译器就完成了它的工作。

编辑:似乎标准(至少n3337)并没有确切地说编译器应该如何被调用-它基本上只是说

注意:虚函数调用的解释取决于它所针对的对象的类型调用(动态类型),而非虚成员函数调用的解释取决于只能在表示该对象的指针或引用的类型(静态类型)上使用(5.2.2)。-结束提示