Ohn*_*hel -2 c++ internals vptr
例子
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <iomanip>
struct father
{
int variable;
father(){variable=0xEEEEEEEE;};
virtual void sing(){printf("trollolo,%x\n",variable);}
~father(){};
};
struct son:father
{
son(){variable=0xDDDDDDDD;};
virtual void sing(){printf("trillili,%x\n",variable);}
~son(){};
};
int main()
{
father * ifather=new(father);
son * ison=new(son);
father uncle;
father * iteachers;
*((long long*)&uncle)=0xDEAF;
iteachers=(father*)malloc(20*sizeof(father));
//ineffective assignments
iteachers[0]=*ifather;
uncle=*ifather;
ifather->sing();//called to prevent optimization
ison->sing();//only to prevent optimization
std::cout.setf(std::ios::hex);
std::cout<<"father:"<<*((long long*)ifather)<<","<<std::endl;
std::cout<<"teacher0:"<<*((long long*)&(iteachers[0]))<<","<<std::endl;
std::cout<<"uncle:"<<*((long long*)&uncle)<<","<<std::endl;
std::cout<<"(son:"<<*((long long*)ison)<<"),"<<std::endl;
// uncle.sing();//would crash
}
Run Code Online (Sandbox Code Playgroud)
使用 gcc 编译时,teachers[0] 的 vtable 指针为零。叔叔的 vtable 指针也保持其原始值而不是被覆盖。我的问题:为什么会这样?有干净的解决方法吗?我uncle._vptr=ifather->_vptr可以随身携带吗?复制对象的普通例程是什么?我什至应该提交一个错误吗?注意:它应该复制整个对象平台无关,因为无论对象类型的识别如何进行,因为它应该始终在对象的数据块内!
文章
没有帮助我,那一定有不同的原因。
据我了解,基本上问题是这段代码是否:
#include <iostream>
using namespace std;
struct Base
{
virtual void sing() { cout << "Base!" << endl; }
virtual ~Base() {}
};
struct Derived: Base
{
void sing() override { cout << "Derived!" << endl; }
};
auto main()
-> int
{
Base* p = new Derived();
*p = Base();
p->sing(); // Reporting "Base" or "Derived"?
}
Run Code Online (Sandbox Code Playgroud)
应该报告“Base”或“Derived”。
简而言之,赋值不会改变对象的类型。
因此,它报告“派生”。