返回信息流为了验证一个问题,先贴测试代码
//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)。到底复制了多大,是基类还是基类+派生类?
这是一条镜像帖。来源:北邮人论坛 / cpp / #73283同步于 2013/8/19
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
关于对象copy的一个小问题
wanderer
2013/8/19镜像同步7 回复
订阅后,新回复会通过你的通知中心匿名送达。
7 条回复
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>
: ...................
【 在 tonyjansan 的大作中提到: 】
: change
: int size = sizeof(*pbas);
: // ...
: ...................
女神每次不说话 只解决问题 纯吊跪舔
搞清楚内存中存放东西就能得出结论
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是一个基类指针,不管指那里,掉用非虚函数肯定是调用自己的函数,不会调派生类函数
谢谢你的回复,关于有虚函数成员的继承的类,在内存中的分布,好像是编译器相关的,我VS2008显示确实是24.
我又修改了一下问题,在原文用红色字体表示的地方,望指教。
【 在 iliketour 的大作中提到: 】
: 搞清楚内存中存放东西就能得出结论
: pbase 存放内容[base ptr] [[vptr] [a]int [b]double] [b]int 其中vptr有派生类display函数
: pcopy本来存放[vptr] [a] [b]
: ...................
我感觉你不理解指向派生类的基类指针这个东西,类在内存中分布也很模糊
【 在 wanderer 的大作中提到: 】
: 谢谢你的回复,关于有虚函数成员的继承的类,在内存中的分布,好像是编译器相关的,我VS2008显示确实是24.
: 我又修改了一下问题,在原文用红色字体表示的地方,望指教。
问题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字节