如何在c ++中将指向基类的指针赋给派生类的对象?

时间:2014-06-21 01:19:40

标签: c++ class pointers base assign

这很难解释,所以这里有一个例子:

class A
{
...
}

class B: public A
{
...
}

vector<A *> v;    // contains pointers to objects of both type A and type B

B item1;

item1 = *v[0];    // *v[0] in this case is an object of type B

除非我收到错误no match for ‘operator=’ (operand types are ‘B’ and ‘A’)no known conversion for argument 1 from ‘A’ to ‘const B&’,否则我会检查以确保v [0]属于B类型,然后再将其分配给item1。

我意识到如果我试图将A的对象分配给其派生类的对象,这可能会产生问题,但这是检查的目的。我该如何解决这个问题?我是否需要做一些完全不同的事情,或者让操作员或类似的事情过载?任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:7)

item1 = *v[0];

上述分配不起作用,因为解除引用v[0]的静态类型为A,并且您尝试将其分配给B对象。

如果您知道v[0]包含指向B对象的指针,则可以static_cast

item1 = *static_cast<B*>(v[0]); // note that a copy is stored in item1

如果您不知道v[0]是否包含指向AB的指针,您可以使用dynamic_cast

进行测试
auto ptr = dynamic_cast<B*>(v[0]);
if(ptr) {
  item1 = *ptr;
}

要使dynamic_cast生效,您的A课程必须包含至少一个virtual功能。


最后,反对在容器中存储原始指针的通常建议。假设您在v内动态分配对象,而不是vector<A*>,则应使用vector<unique_ptr<A>>。此外,如果您要通过delete转发A *这些对象,则A的析构函数必须为virtual

class A
{
  ...
  virtual ~A() = default;
};

答案 1 :(得分:2)

这就是dynamic_cast的作用。

if ( B* b = dynamic_cast<B*>(v[0]) )
{
    item1 = *b;    // *v[0] in this case is an object of type B
}