如何将基础对象分配给派生对象
我有一个关于C++的问题,如何将基础对象分配给派生对象?或者如何将指向Base对象的指针分配给指向Derived对象的指针?如何将基础对象分配给派生对象
在下面的代码中,这两行是错误的。如何纠正?
#include <iostream>
using namespace std;
class A{
public:
int a;
};
class B:public A{
public:
int b;
};
int main(){
A a;
B b;
b = a; //what happend?
cout << b.b << endl;
B* b2;
b2 = &a; // what happened?
cout << b->b << endl;
}
当一个对象位于堆栈上时,只能真正将相同类型的对象分配给另一个对象。它们可以通过重载的转换操作符或重载的赋值操作符进行转换,但是您在此处指定了转换。编译器不能自己做这样的转换。
A a;
B b;
b = a;
在这种情况下,您试图将A分配给B,但A不是B,所以它不起作用。
A a;
B b;
a = b;
这是一种时尚,但它可能不会是你期望的。你刚刚把你的B切成了B,B是A,所以赋值可以发生,但是因为它在堆栈上,它只是将a的一部分b分配给a。所以,你得到的是一个A.这不,尽管如果你真的想成为一个指定类型的对象到另一个,他们需要的指针,你从B.
分配的事实B中。
A* pa = NULL;
B* pb = new B;
pa = pb;
This Works。现在pa指向pb,所以它仍然是B.如果你在A上有虚拟函数而B覆盖了它们,那么当你在pa上调用它们时,它们将调用B版本(非虚拟函数仍然会调用A版本)。
A* pa = new A;
B* pb = pa;
这是行不通的。 PA不点B,所以不能将其指定为PB必须指向B.仅仅因为B是A不意味着比A是B.
A a;
B* pb = &a;
这并未因为和上一个相同的原因工作。它恰好是这样的,A这次是堆栈而不是堆栈。
A* pa;
B b;
pa = &b;
这是行不通的。 b是B是A,所以A可以指向它。虚拟功能将调用B版本,非虚拟功能将调用A版本。
所以,基本上,A *可以指向,因为B是A,B *不能指向A,因为它不是一个B.
b = a; //what happend?
这是明显的违法 - A不是B,所以你不能做到这一点。
b2 = &a; // what happened?
同样在这里。
在任何情况下,编译器都不知道要分配给int b
,因此他阻止你这么做。另一种方式(分配派生到基地)的作品,因为基地是一个派生的子集。
现在,如果你想告诉我们,你想达到的是什么,我们可能会帮助你。
如果它的分配被称为是一个派生类的A的情况下,你可以做一个投:
A* a = new B();
B* b = dynamic_cast<B>(a);
只要记住,如果a
不是B
然后将dynamic_cast将返回NULL。请注意,此方法仅适用于指针,原因是。
将基础对象分配给派生指针(或指向派生指针的基指针)是没有意义的,因此C++将尽其所能阻止您这样做。唯一的例外是当基指针真正指向的派生,在这种情况下,你可以使用动态转换:
base * p = new derived;
derived * d = dynamic_cast <derived *>(p);
在这种情况下,如果p其实指向一个基地,指针d将包含NULL。
编译器不会允许这样的事情。即使你通过一些黑客行为来做到这一点,这样做也没有意义。将派生对象分配给基类的指针是有意义的,因为基类所能做的所有事情都可以派生出来。但是,如果允许相反的情况,如果您尝试访问派生的基础对象中定义的成员,该怎么办?您将尝试访问充满垃圾或无关数据的内存区域。
派生对象是一种Base对象,而不是其他方式。
也适用于引用,在以下情况下抛出一个异常B的失败。但是,dynamic_cast似乎需要虚拟方法(例如向A添加虚拟析构函数) – UncleBens 2010-01-30 00:44:54