C++简单问题

soft_jianbiao 2009-03-15 03:50:33
请问在C++中,如果我定义这样两个类
class A
{
public:
int m;
};
class B : public A
{
public
int n;
};

然后
B b;
A a = b;
这样以后,在内存里a这个对象到底是怎么样存放的?
还有一个对象在内存存放以后,系统是怎么知道他的边界的!
...全文
539 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
ForestDB 2009-03-16
  • 打赏
  • 举报
回复
Inside C++ Object Model.
感兴趣的话去看看吧。
sunnystone614 2009-03-16
  • 打赏
  • 举报
回复
实际上b是两个部分组成的一个是a部分一个是b部分,在初始化 b 的时候,是经过2个步骤的,首先需要先初始化基类a的部分,然后是b的部分,在把派生类赋给基类的时候只能把基类的部分赋给a,也就是发生了切割。
边界,这个和你声明的对象类型有关吧。呃,上面都说那么全了啊
zhoulehua 2009-03-16
  • 打赏
  • 举报
回复
顶起高手们
csjtxy 2009-03-16
  • 打赏
  • 举报
回复
先顶起来
Z_L_H 2009-03-16
  • 打赏
  • 举报
回复
4楼也是不错的。
就呆在云上 2009-03-16
  • 打赏
  • 举报
回复
然后 
B b;
A a = b;



你这个就是一个slice,切片了,从子类到父类的直接复制,而不是通过引用和指针都是这个结果
那么a就是一个a对象
那么a的内存里面就只有一个int m;4个字节而已
saintswordsman 2009-03-16
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 liumingrong 的回复:]
B类对象b实际上在内存中有连续的两部分,一个是从基类继承的数据m,一个是自己定义的数据n
A a = b; 产生一个A类对象,它用b的基类部分初始化自己
对象的大小是编译器根据其类型决定的
感兴趣的话推荐看 深度探索c++对象模型
[/Quote]

对象大小的确定,可以去看看内存对齐方面的讲解。结构体也涉及这方面的知识。
gadx86 2009-03-16
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 pengzhixi 的回复:]
对于你这种情况,在对象b的起始地址那段内存存放A中的成员m,接下来就存放B中的成员n。而你用对象b来给A类型的对象a赋值时,实际上只将对象b中的属于A的那部分赋值给对象a
[/Quote]
UP
konhon 2009-03-16
  • 打赏
  • 举报
回复
A a = b;
a实例只接收b实例的类A部分数据。

如果只是你上面的声明, 应该是a实例只接收b实例的类A部分数据。
如果有虚函数, 那情况就不同了
ysysbaobei 2009-03-16
  • 打赏
  • 举报
回复
sagegz 2009-03-16
  • 打赏
  • 举报
回复
B b;
A a = b;
-------------
用派生类给基类赋值,基类只接受派生类中从基类继承下来的成员进行赋值.
它们共享一段内存单元,a和b的起始地址是相同的.
  • 打赏
  • 举报
回复
A a = b;
a实例只接收b实例的类A部分数据。
楼主可以看看C++ primer,讲的很清楚.
fairchild811 2009-03-15
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 liumingrong 的回复:]
B类对象b实际上在内存中有连续的两部分,一个是从基类继承的数据m,一个是自己定义的数据n
A a = b; 产生一个A类对象,它用b的基类部分初始化自己
对象的大小是编译器根据其类型决定的


正确
chin_chen 2009-03-15
  • 打赏
  • 举报
回复
[Quote=引用楼主 soft_jianbiao 的帖子:]
请问在C++中,如果我定义这样两个类
class A
{
public:
int m;
};
class B : public A
{
public
int n;
};

然后
B b;
A a = b;
这样以后,在内存里a这个对象到底是怎么样存放的?
还有一个对象在内存存放以后,系统是怎么知道他的边界的!
[/Quote]你这么赋值的话,对象会切割的。就是把B面A的部分提出来赋值给a。
a的内存就是一块固定的区域,每个成员都有自己一部分空间,如果是有虚函数的,额外加上虚指针之类的。

关于边界,就是每个结构体都有固定的大小,一旦你定义了一个变量,就申请了相应大小的内存地址啊。至于类里面怎么寻址的。是由自己的机制的。
arong1234 2009-03-15
  • 打赏
  • 举报
回复
实际上编译器把对象的地址固定后,代码内部是硬记地址的。
例如,他可能用mov ecx, [esp+12]这样的东西来访问一个临时变量的this指针,12就是硬编码的
所以运行时刻的边界和地址都是编译时直接或者间接确定的
rivulettornado 2009-03-15
  • 打赏
  • 举报
回复
这就是好像调用形成的递归
飞哥 2009-03-15
  • 打赏
  • 举报
回复
成员变量在内存中是在内存对齐的格式下顺序存储的。
如果子类给基类赋值,就可能造成“切割”,很多时候这样的赋值是危险的,需要自己定义拷贝函数。

边界? 瞧这段连续的内存
pengzhixi 2009-03-15
  • 打赏
  • 举报
回复

#include <iostream>
using namespace std;

class A
{
public:
int m;
A():m(2){cout<<"the m's address is:"<<&m<<endl;};
};
class B : public A
{
public:
int n ;
B():n(3){cout<<"the n's address is:"<<&n<<endl;};
};

int main()
{
B b;
A a = b;
system("pause");
return 0;
}


这个程序能更好帮你理解了
cnStreamlet 2009-03-15
  • 打赏
  • 举报
回复
顶1楼
yangch_nhcmo 2009-03-15
  • 打赏
  • 举报
回复
楼主运行下面的代码看一下就大概能清楚了

#include <iostream>
using namespace std;

class A
{
public:
int m;
A():m(2){};
};
class B : public A
{
public:
int n ;
B():n(3){};
};

int main()
{
B b;
A a = b;

cout << "a SIZE:" << sizeof(a) << endl; // a中只存放有int m, 其大小为4
cout << "b SIZE:" << sizeof(b) << endl; // b中存放有int m, int n,其大小为8

cout << "a.m: " << a.m << endl; //a中只存有int m
cout << "b.m: " << b.m << endl; //b中存有int m , int n
cout << "b.n: " << b.n << endl;


return 0;
}
加载更多回复(3)

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧