向下转型 `vector<Parent>`

Eli*_*iad 3 c++ class downcast

我的程序中存在向上转型和向下转型的问题。我有一个vector<Child>被传递给一个期望的函数const vector<Parent>& pp。到目前为止没有问题(编辑:显然有!请参阅评论)。但是,现在我想传递pp给一个期望的函数const vector<Child>& cc,但我不能这样做。

我应该如何做到这一点,同时我不赋予函数修改原始类的能力?您能否列出执行此操作的各种方法,最好列出它们的优缺点?

Mat*_*zok 5

有一种东西叫变异。它有 3 种口味:

  • 不变性- 即使B扩展AT<B>不扩展T<A>
  • 协变- 当B扩展时A,然后T<B>扩展T<A>
  • 逆变- 当B延伸时A,则T<A>延伸T<B>

当谈到 C++ 模板时,你最终会得到不变性。尽管从名字上看它们看起来是一样的:vector<Parent>而且vector<Child>它们是两种不同的类型。

如果您查看编译器生成的内容,它们都会对可能具有不同大小的类型进行操作。由于C++ 依赖于对象大小的知识(例如,当它计算对象在数组中的位置时),因此Child[]无法将eg 类型强制转换为Parent[],因为某些对象的位置可能会被错误计算。出于同样的原因,模板以不变的方式运行:编译器无法猜测何时会执行此类转换以及何时不安全执行此类转换。

所以这取决于你来解决这个问题,并且你在这里有一些选择。一种方法是创建也采用该参数模板的函数:

template<T>
void performAction(vector<T> objects) {
  // ...
}
Run Code Online (Sandbox Code Playgroud)

其他的方法是用(智能)指针替换值——它们可以轻松处理多态性。

编辑:

为了具体说明我在上一句中的意思:您可以简单地使用vector< unique_ptr<Parent> >vector< shared_ptr<Parent> >存储Parent(包括Child)的任何实例,因此您不必执行容器的任何转换。

  • 关于您的最后一段:“vector&lt;Parent*&gt;”和“vector&lt;Child*&gt;”同样不相关,您必须在任何地方使用“vector&lt;Parent*&gt;”。 (2认同)