C++ C++;按值调用虚函数

C++ C++;按值调用虚函数,c++,C++,我试图修改Base对象的vfptr,以指向派生的类所拥有的vtable: #include<iostream> using namespace std; class Base { public: virtual void func() { cout << "Base::func()" << endl; } Base() = default; Base(const Base&); }; Base::Base(c

我试图修改
Base
对象的vfptr,以指向
派生的类所拥有的vtable:

#include<iostream>
using namespace std;
class Base {
public:
    virtual void func() { cout << "Base::func()" << endl; }
    Base() = default;
    Base(const Base&);
};
Base::Base(const Base&b) {
    *((int*)(this)) = *((int*)(&b));  //modify the vfptr
}
class Derived : public Base {
public:
    virtual void func() { cout << "Derived::func()" << endl; }
};
int main() {
    Derived d;
    cout << "Derived's vtable: " << *(int*)&d << endl << endl;
    Base b = d;
    cout << "Base's vtable: " << *(int*)&b << endl << endl;

    cout << "pass by value:" << endl;
    b.func();
    cout << endl;
    Base *bp = &b;
    cout << "pass by pointer" << endl;
    bp->func();
}
我们可以看到,对象
b
的vfptr在修改后确实指向
派生的
vtable,但仍然按值调用
Base
version
func()

我想知道编译器是否通过静态绑定处理此类值调用,即使调用的是虚拟函数?
非常感谢你

我想知道编译器是否通过静态绑定处理这样的值调用

Base b = d;
b.func();

是的,它确实在这里进行静态绑定。事实上,使用动态绑定是毫无意义的,因为在编译时,已知对象的动态类型与静态类型相同。

编译器可能会对调用进行反虚拟化,如果知道它正在处理的确切类型,这是很好的。您可以通过检查程序集来检查这一点。不相关,但我希望这只是为了实验。虚拟调用只针对指针和引用进行。对于来自静态类型对象的调用,它们是完全冗余的,因此编译器完全绕过了vptr。Vtables在标准中根本没有提及,只是一个实现细节。尝试访问/修改它们充其量是实现定义的行为,尤其是在您假装
*这
int
时,未定义的行为。编译器的任务是将源代码描述的可观察行为转换为执行该行为的机器指令。如果所描述的行为不需要动态分派,编译器可以丢弃用于动态分派的机器。请参见最重要的一点,
Base b=d
did对象切片。
b
对象的类型为
Base
,而不是
派生的
。与VPTR玩恶作剧只会带来麻烦。
Base b = d;
b.func();