gpt4 book ai didi

c++ - memcpy派生类转基类,为什么还是调用基类函数

转载 作者:行者123 更新时间:2023-11-30 02:28:07 26 4
gpt4 key购买 nike

我正在阅读 Inside the C++ Object Model。 1.3节中

So, then, why is it that, given

Bear b; 
ZooAnimal za = b;

// ZooAnimal::rotate() invoked
za.rotate();

the instance of rotate() invoked is the ZooAnimal instance and not that of Bear? Moreover, if memberwise initialization copies the values of one object to another, why is za's vptr not addressing Bear's virtual table?

The answer to the second question is that the compiler intercedes in the initialization and assignment of one class object with another. The compiler must ensure that if an object contains one or more vptrs, those vptr values are not initialized or changed by the source object .

所以我写了下面的测试代码:

#include <stdio.h>
class Base{
public:
virtual void vfunc() { puts("Base::vfunc()"); }
};
class Derived: public Base
{
public:
virtual void vfunc() { puts("Derived::vfunc()"); }
};
#include <string.h>

int main()
{
Derived d;
Base b_assign = d;
Base b_memcpy;
memcpy(&b_memcpy, &d, sizeof(Base));

b_assign.vfunc();
b_memcpy.vfunc();

printf("sizeof Base : %d\n", sizeof(Base));

Base &b_ref = d;
b_ref.vfunc();

printf("b_assign: %x; b_memcpy: %x; b_ref: %x\n",
*(int *)&b_assign,
*(int *)&b_memcpy,
*(int *)&b_ref);
return 0;
}

result

Base::vfunc()
Base::vfunc()
sizeof Base : 4
Derived::vfunc()
b_assign: 80487b4; b_memcpy: 8048780; b_ref: 8048780

我的问题是为什么 b_memcpy 仍然调用 Base::vfunc()

最佳答案

你所做的在 C++ 语言中是非法的,这意味着你的 b_memcpy 对象的行为是未定义的。后者意味着任何行为都是“正确的”,而你的期望是完全没有根据的。尝试分析未定义的行为没有多大意义 - 它不应该遵循任何逻辑。

实际上,您对 memcpy 的操作很有可能确实将 Derived 的虚拟表指针复制到 b_memcpy 对象。您对 b_ref 的实验证实了这一点。但是,当通过直接对象调用虚拟方法时(如 b_memcpy.vfunc() 调用的情况),大多数实现优化了对虚拟表的访问并执行直接(非虚拟)调用目标函数。该语言的正式规则规定,任何法律行动都不能使 b_memcpy.vfunc() 调用分派(dispatch)给 Base::vfunc() 以外的任何东西,这就是为什么编译器可以安全地将此调用替换为对 Base::vfunc() 的直接调用。这就是为什么任何虚拟表操作通常对 b_memcpy.vfunc() 调用没有影响。

关于c++ - memcpy派生类转基类,为什么还是调用基类函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41094195/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com