一直苦恼的父类子类/父类指针子类指针转换的问题

austin_minny 2010-02-24 10:59:45
我有
class A
{
int m_a;
};

class B:public A
{
char m_b;
};

A a;
B b;
A* pa = new A;
B* pb = new B;


我想请问:
a能否转换为b
b能否转换为a
pa能否转换为pb
pb能否转换为pa

如果能转换的,如果会引发什么问题,也请帮小弟提醒一下


困扰了很久,先是学 COM发现里面接口父类转成子类,后来做可序列化的类又看到CObject和子类转来转去的,换成指针就更晕了,请各位大侠赐教!
...全文
1576 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
CG 2012-07-08
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 的回复:]

引用 8 楼 lrqsf 的回复:
引用 6 楼 we_sky2008 的回复:
不只是简单的切片吧?


内存模型考虑,理解为切有什么不对吗?向上强制转型肯定要被切割的。


这位童鞋,你的切片,感觉不太对。给个例子,你分析一下:
class A
{
int a;
void test(){cout<<"A"<<endl;}
}
class B:publi……
[/Quote]

切片针对的是对象之间的转换吧,指针之间的转换应该没有切片的现象。
austin_minny 2012-03-11
  • 打赏
  • 举报
回复
理解类内部原理
zhangyan0822 2011-11-01
  • 打赏
  • 举报
回复
主楼去买本计算机理解计算机系统,看完了,就可以给他们讲讲是为什么了。
yangxiaoluck 2011-07-21
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 lrqsf 的回复:]
引用 6 楼 we_sky2008 的回复:
不只是简单的切片吧?


内存模型考虑,理解为切有什么不对吗?向上强制转型肯定要被切割的。
[/Quote]

这位童鞋,你的切片,感觉不太对。给个例子,你分析一下:
class A
{
int a;
void test(){cout<<"A"<<endl;}
}
class B:public A
{
int b;
void test(){cout<<"B"<<endl;}
}
A* pa;
B* pb;
pa=pb;
这个时候还存在切片么,你的意思就是说切片,把test()函数切掉了还是怎么地。但是这里,test被重载了啊,也就是说这个时候调用的还是B的test,但实际上不是这样的。所以单纯的切片无法解释,谢谢。本人菜鸟
lrqsf 2010-02-26
  • 打赏
  • 举报
回复
引用 20 楼 baihacker 的回复:
vptr这些,会有一段thunk进行指针重设。


恩,C++编程思想第1章对象导言也是这样说的。并在15章有很详细的说明

To perform late binding, the C++ compiler inserts a special bit of
code in lieu of the absolute call. This code calculates the address of
the function body, using information stored in the object (this
process is covered in great detail in Chapter 15). Thus, each object
can behave differently according to the contents of that special bit
of code. When you send a message to an object, the object actually
does figure out what to do with that message.
lrqsf 2010-02-26
  • 打赏
  • 举报
回复
引用 14 楼 lrqsf 的回复:
如果有虚函数,子类开始第一个位置必定是vptr的,还有向上强制转换实际上是编译器执行了父类的拷贝构造函数,并且是按值传递,不是按地址。


子类开始第一个位置必定是vptr的。
我这个说法不准确,应该说都是相同位置(但常常是在第一个位置)。更正一下。
gueangyik 2010-02-26
  • 打赏
  • 举报
回复
引用 12 楼 pengzhixi 的回复:
a能否转换为b
a不能转换为b当然你要强制转换也行,但是后果自负

b能否转换为a
b转换为a没问题,会发生截断

pa能否转换为pb
你将pa转换为pb没问题,但是你一旦调用了B里面特有的成员的时候你会出错

pb能否转换为pa
这个当然没问题

lrqsf 2010-02-25
  • 打赏
  • 举报
回复
引用 16 楼 we_sky2008 的回复:
引用 14 楼 lrqsf 的回复:如果有虚函数,子类开始第一个位置必定是vptr的,还有向上强制转换实际上是编译器执行了父类的拷贝构造函数,并且是按值传递,不是按地址。
呵呵,
的确是这样的

呵呵,大家一起学习。多交流。
adventurelw 2010-02-25
  • 打赏
  • 举报
回复
用dynamic_cast研究一下就明白了吧
pa可以等于new B;
但pb = new A是不行的

a可以等于b
但b = a是不完整的,可能出问题的。
we_sky2008 2010-02-25
  • 打赏
  • 举报
回复
引用 14 楼 lrqsf 的回复:
如果有虚函数,子类开始第一个位置必定是vptr的,还有向上强制转换实际上是编译器执行了父类的拷贝构造函数,并且是按值传递,不是按地址。

呵呵,
的确是这样的
we_sky2008 2010-02-25
  • 打赏
  • 举报
回复
引用 13 楼 we_sky2008 的回复:
引用 8 楼 lrqsf 的回复:引用 6 楼 we_sky2008 的回复:不只是简单的切片吧? 内存模型考虑,理解为切有什么不对吗?向上强制转型肯定要被切割的。
有虚函数存在的话
vptr怎么处理?

呵呵,
可能是我们对'切片'的含义理解不同
我理解的切片是简单的切掉后面(派生类成员)的部分,前面部分保持
而实际上vptr一般是存放在对象的最前面,如果简单切除的话
vptr则实际可能还是指向派生类的虚表
但是实际上有可能会调用基类拷贝构造函数创建对象,编译器再自动安插指向基类虚表的vptr
lrqsf 2010-02-25
  • 打赏
  • 举报
回复
如果有虚函数,子类开始第一个位置必定是vptr的,还有向上强制转换实际上是编译器执行了父类的拷贝构造函数,并且是按值传递,不是按地址。
we_sky2008 2010-02-25
  • 打赏
  • 举报
回复
引用 8 楼 lrqsf 的回复:
引用 6 楼 we_sky2008 的回复:不只是简单的切片吧?

内存模型考虑,理解为切有什么不对吗?向上强制转型肯定要被切割的。

有虚函数存在的话
vptr怎么处理?
pengzhixi 2010-02-25
  • 打赏
  • 举报
回复
a能否转换为b
a不能转换为b当然你要强制转换也行,但是后果自负

b能否转换为a
b转换为a没问题,会发生截断

pa能否转换为pb
你将pa转换为pb没问题,但是你一旦调用了B里面特有的成员的时候你会出错

pb能否转换为pa
这个当然没问题
欣客 2010-02-25
  • 打赏
  • 举报
回复
对象不能转换。
父类的指针可以指向子类(子类对象的指针可以给父类类型的指针),子类的不能指向父类(通不过编译器)
ArthurJava 2010-02-25
  • 打赏
  • 举报
回复
继承的关系是is-a的关系
yshuise 2010-02-25
  • 打赏
  • 举报
回复
这儿pa是不能转换成pb的。道理很简单,这两个是独立的对象(a,b)。
但是如果是同一个对象(b),倒可以转换成指向基类或是子类的指针。
lrqsf 2010-02-25
  • 打赏
  • 举报
回复
引用 6 楼 we_sky2008 的回复:
不只是简单的切片吧?


内存模型考虑,理解为切有什么不对吗?向上强制转型肯定要被切割的。
fairuyy 2010-02-25
  • 打赏
  • 举报
回复
呵呵,初学者都挺晕的,特别是指针和继承
we_sky2008 2010-02-25
  • 打赏
  • 举报
回复
引用 3 楼 lrqsf 的回复:
1楼大大以说了。可以用内存模型来考虑,子类占用的内存至少不能小于父内,那么子类转父类肯定是要被切片。的。C++是门成熟的语言,用你现实生活来思考他吧。

不只是简单的切片吧?
加载更多回复(5)

64,649

社区成员

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

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