- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在阅读 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;
}
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/
这个问题在这里已经有了答案: 关闭 13 年前。 重复: Memcpy() in secure programming? 根据“Please Join me in welcoming memcpy(
这个问题在这里已经有了答案: 关闭 13 年前。 重复: Memcpy() in secure programming? 根据“Please Join me in welcoming memcpy(
众所周知,在x86 / x86_64之类的多字节字计算机中,逐字节地复制/移动大量内存(每步4或8个字节)要比逐字节地复制/移动更为有效。 我很好奇strncpy / memcpy / memmove
我需要帮助,我正在尝试使用 memcpy 在内核空间复制 header ,但屏幕变黑,看起来它不喜欢我的 memcpy。请有人帮助我。 remaining = ntohs(iphead
我在使用 memcpy() 时遇到了一点问题 当我写这篇文章时 char ipA[15], ipB[15]; size_t b = 15; memcpy(ipA,line+15,b); 它从数组 li
我正在尝试将一些 libc 代码移植到 Rust。具体来说,__tcgetattr()函数found in this file . 我只有一个部分遇到问题。 if (sizeof (cc_t) ==
我在玩 memcpy 时偶然发现了一个奇怪的结果,在 bool memcpy 之后对同一内存指针调用的 memcpy 给出了意想不到的结果。 我创建了一个简单的测试结构,其中包含一堆不同类型的变量。我
Memcpy 和 memcmp 函数可以接受指针变量吗? char *p; char* q; memcpy(p,q,10); //will this work? memcmp(p,q,10); //w
我将创建一些具有虚拟复制功能的父类和子类,它返回自身的拷贝: class A{ public: int ID; virtual A* copy(){ retur
这是引用自 C11 标准: 6.5 Expressions ... 6 The effective type of an object for an access to its stored valu
我正在尝试使用 memcpy 将一个二维数组复制到另一个。我的代码: #include #include int print(int arr[][3], int n) { for (int
我编写了一个简单的程序来测试使用 memcpy 将字节从字节缓冲区复制到结构。但是我没有得到预期的结果。 我分配了一个 100 字节的缓冲区,并将值设置为 0、1、2...99。然后我将这些字节复制到
如果有一个普通类型的有效对象(在这种情况下,普通类型满足普通移动/复制可构造的概念),并且一个 memcpy 将它放到未初始化的内存区域,复制的内存区域是有效对象吗? 我读到的假设:一个对象只有在它的
我正在研究 Arduino 并尝试更改数组的元素。在设置之前,我像这样初始化数组: bool updateArea[5] = { false }; 然后我想像这样更改数组: updateArea[0]
在 Cuda 中运行我的程序时遇到“未指定的启动失败”。 我检查了错误。 该程序是一个微分方程的求解器。它迭代 TOTAL_ITER 次。 ROOM_X 和 ROOM_Y 是矩阵的宽度和高度。 这是标
我试图将双缓冲放入我的 VGA dos 程序中,但是当我使用 memcpy 函数时似乎出现了问题。 我确信我分配了所需的内存,但它似乎不起作用。 程序如下: #include #include u
我一直认为 memcpy() 可以用于恶意目的。我做了几个测试应用程序,看看我是否可以从不同区域“窃取”内存中的数据。到目前为止,我已经测试了三个区域,堆、堆栈和常量(只读)内存。在我的测试中,常量内
这是一项家庭作业。我想实现 memcpy()。有人告诉我内存区域不能重叠。其实我不明白那是什么意思,因为这段代码工作正常,但是有内存重叠的可能性。如何预防? void *mem_copy(void *
问题是,当我们使用 memcpy() 复制任何字节数组时,我们应该明确声明目标缓冲区的起始(第 0 个)索引,还是简单地提及它就足够了。让我展示我在说什么的例子。假设我们正在尝试将源缓冲区复制到目标缓
我只是想将一个结构复制到另一个结构(按值复制,而不是按引用复制)。这是完整的工作代码 /* memcpy example */ #include #include #include #defin
我是一名优秀的程序员,十分优秀!