class a
{
int var;
}
class b :public a
{
int var2,var3;
}
int main()
{
a *poi;
poi=new b;
//b *poi2;
//poi2=new a;
return 0
}
在上面的代码中,我能够使用指向基类指针变量的派生类类型来分配内存。
,a *poi=new b;
但是我无法使用指向派生类指针的基类类型来分配内存。
即b *poi=new a;
为什么不能进行以下内存分配? 它背后的逻辑是什么?
答案 0 :(得分:4)
这不是关于内存分配而是关于继承。
Fruit* f = new Apple
运作良好,但
Apple* a = new Fruit
会给你一个不完整的苹果,甚至是香蕉,所以编译器不允许你这样做。
两个指针都有相同的大小,您可以使用unsafe static cast 将水果指针存储到苹果指针中,但是您应该避免这样做
答案 1 :(得分:2)
这与内存分配没有任何关系。简单地说,第一次转换是有效的隐式转换(从派生类指针到基指针),但第二次转换不是(从基类指向派生指针):
§4.10/ 3 [conv.ptr] 类型为“指向cv D的指针”的prvalue,其中D是类类型,可以转换为“指向cv B的指针”的prvalue “,其中B是D的基类(第10条)。
原因是多态性代表 is-a 关系。 b
是 a
,但a
不是b
。因此,您可以使a
指针指向b
,因为它指向的对象是有效的a
对象。但是,您不能将b
指针指向a
,因为a
对象不一定是有效的b
对象。
答案 2 :(得分:1)
此处a *poi;
poi=new b;
有效,因为poi
的引用为var
,b
的对象也具有变量var
,因为继承。这是一个有效的参考。
如果b *poi2;
poi2=new a;
poi2
也可以引用var2
和var3
,但a
的对象不包含{ {1}}和var2
。这会导致无效的引用。
我的意思是var3
是一个有效的语句,但如果编译器允许poi2->var2
则var2
没有poi2=new a;
,那么poi2->var2
将指向无效的内存段。