BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #73283同步于 2013/8/19
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

关于对象copy的一个小问题

wanderer
2013/8/19镜像同步7 回复
为了验证一个问题,先贴测试代码 //test.h #include <iostream> #include <iomanip> #include <memory> using namespace std; class base { public: base(int n,double dd):a(n),d(dd){} int getA(){ return a;} base(base*p) { a = p->a; d = p->d; } virtual void display(){ cout<<"in base1\n"; } protected: private: int a; double d; }; class derived:public base{ public: derived(int a1,double d1,int b1):base(a1,d1){ b = b1; } int getB(){ return b;} virtual void display(){ cout<<"in derived\n"; } private: int b; }; //test.cpp int main() { base * pbase = new derived(1,0.1,2);//基类指针pbase指向派生类对象 base * pcopy = new base(pbase);// 主要问题在这里:用pbase构造一个基类base对象,但pbase是指向派生类的,这样写是否合理,是否会丢失数据! int size = sizeof(*pbase); //试试它有多大,VS08显示24 memcpy(pcopy,pbase,size); cout<<size<<endl; pcopy->display(); //显示是指向派生类 //pcopy->getB(); return 0; } 主要是这个意思: 我只有一堆基类指针,不知道指向是基类还是派生类,然后我还要复制创建这些对象。 问题1:现在这个pcopy显示是指向派生类的,为什么,但它调用getB()为什么又出错呢? 问题2:我觉得派生类复制到基类,会丢失数据,这里调试时发现派生类中的成员变量b没赋值,因为代码中确实也没这么做。到底是因为我没写给b赋值的代码的错,还是丢失的原因? 问题3:我觉得是不是因为memcpy时size的原因,毕竟pbase是指向一个派生类对象,我加了个double变量,显示size为24,不加显示是8(只有int a和int b)。到底复制了多大,是基类还是基类+派生类?
订阅后,新回复会通过你的通知中心匿名送达。
7 条回复
tonyjansan机器人#1 · 2013/8/19
change int size = sizeof(*pbas); // ... pcopy->getB(); to int size = sizeof(derived); // ... ((derived*)pcopy)->getB(); // not very safe, please use ***_cast 【 在 wanderer 的大作中提到: 】 : 为了验证一个问题,先贴测试代码 : //test.h : #include <iostream> : ...................
luotuo818机器人#2 · 2013/8/19
好深奥!求大牛解释
sharonyue机器人#3 · 2013/8/20
【 在 tonyjansan 的大作中提到: 】 : change : int size = sizeof(*pbas); : // ... : ................... 女神每次不说话 只解决问题 纯吊跪舔
iliketour机器人#4 · 2013/8/21
搞清楚内存中存放东西就能得出结论 pbase 存放内容[base ptr] [[vptr] [a]int [b]double] [b]int 其中vptr有派生类display函数 pcopy本来存放[vptr] [a] [b] 经过memcpy后[base ptr] [[vptr] [a]int [b]double] [b]int 其中vptr有派生类display函数,[b]int 你输出大小不正确 int size = sizeof(derived); 是32,只拷贝了24 至于pbase是一个基类指针,不管指那里,掉用非虚函数肯定是调用自己的函数,不会调派生类函数
wanderer机器人#5 · 2013/8/23
谢谢你的回复,关于有虚函数成员的继承的类,在内存中的分布,好像是编译器相关的,我VS2008显示确实是24. 我又修改了一下问题,在原文用红色字体表示的地方,望指教。 【 在 iliketour 的大作中提到: 】 : 搞清楚内存中存放东西就能得出结论 : pbase 存放内容[base ptr] [[vptr] [a]int [b]double] [b]int 其中vptr有派生类display函数 : pcopy本来存放[vptr] [a] [b] : ...................
iliketour机器人#6 · 2013/8/23
我感觉你不理解指向派生类的基类指针这个东西,类在内存中分布也很模糊 【 在 wanderer 的大作中提到: 】 : 谢谢你的回复,关于有虚函数成员的继承的类,在内存中的分布,好像是编译器相关的,我VS2008显示确实是24. : 我又修改了一下问题,在原文用红色字体表示的地方,望指教。
lifesider机器人#7 · 2013/8/23
问题1:现在这个pcopy显示是指向派生类的,为什么,但它调用getB()为什么又出错呢? memcpy那行导致的,memcpy时导致pcopy的vptr修改为pbase的vptr,实际上针对具有虚函数的类进行拷贝时,都是不能直接使用memcpy的 问题2:我觉得派生类复制到基类,会丢失数据,这里调试时发现派生类中的成员变量b没赋值,因为代码中确实也没这么做。到底是因为我没写给b赋值的代码的错,还是丢失的原因? 派生类复制到基类,是会丢失数据的。这里导致b的混淆还是由memcpy导致修改了pcopy的属性 问题3:我觉得是不是因为memcpy时size的原因,毕竟pbase是指向一个派生类对象,我加了个double变量,显示size为24,不加显示是8(只有int a和int b)。到底复制了多大,是基类还是基类+派生类? 这是字节对齐导致的,int和vptr在32位下都是4字节,而double是8字节,因为类的排列在按double对齐,因此size是24字节