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

How to assign a pointer to base class to an object of a derived class in c++?

本文关键字:派生 对象 c++ 基类 指针 赋值      更新时间:2023-10-16

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

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的对象赋值给其派生类的对象,这可能会产生问题,但这就是检查的目的。我该怎么解决这个问题?我是否需要做一些完全不同的事情,或者重载操作符或类似的事情?

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>>。同样,如果要通过A *delete这些对象,那么A的析构函数必须是virtual

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

dynamic_cast就是这么做的。

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