C++ V 形转换:vector<Base1*> 到 vector<Base2*>

C++ V-shape casting: vector<Base1*> to vector<Base2*>

我很难弄清楚这个转换问题。以 3 类:

开头
#include <vector>
// Pure virtual class
class Base1{
  public:
   virtual ~Base1();
   virtual void do_sth()=0;
}
class Base2{
  public:
   int prop=3;
   ~Base2();
}
class Derived: public Base1, Base2{
  ~Derived();
  void do_sth(){print("Hi");};
}

如何执行以下转换?

std::vector<Base1*> vec1
vec1.reserve(10);
for( int i = 0; i < 10; ++i )
    vec1.push_back(new Derived());

// To this type...?
std::vector<Base2*> vec2 = ?????;

一些备注:

vec1vec2 中都没有 Derived 对象,因此您无法从其中任何一个的元素获取指向 Derived 的其他基础子对象的指针.

如果将 Derived 传递给 vec1.push_back,它将从 DerivedBase1 子对象复制构造一个 Base1。这称为对象切片。

如果在 vec1 中有指向 Base1 指针 (原始或智能)向量,那么它们可能指向 Base1 Derived 的基础子对象,此时你可以 dynamic_cast<Base2*> 它们,这通常会给你一个不同的指针值。

问题的评论变得相当混乱,所以我将 post 在此部分回答,而不是试图理清评论。

Base1 有虚函数。好的开始。

Derived 派生自 Base1.

Derived 也派生自 Base2.

如果您有一个 Derived 类型的对象,您可以创建一个指向 Base1 的指针,该指针指向派生对象:

Derived d;
Base1* b1 = &d;

现在你有一个指向多态基的指针class,你可以使用dynamic_cast来执行交叉转换:

Base2* b2 = dynamic_cast<Base2*>(b1);

编译器知道如何做到这一点,结果应该与您直接获得的指针值相同:

Base2* b2x = &d;
assert(b2x == b2);

还请注意,由于代码在指针向量中传输,因此 Derived 对象似乎是使用 new Derived 创建的。如果是这样,并且最终代码通过指向其中一种基类型的指针删除了 Derived 对象,那么基类型 必须 具有虚拟析构函数。