向下转换`vector<Parent>`

Downcasting `vector<Parent>`

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

我应该怎么做,同时我又不给函数修改原来的能力类?您能否列出各种方法,最好列出它们的优缺点?

即使 Child 派生自 Parent 或相反,vector<Child>vector<Parent> 也不相关,它们是不同的类型。

有一种东西叫做变异。它有 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[] 无法转换为 Parent[],因为某些对象的位置可能计算错误。出于同样的原因,模板以不变的方式运行:编译器无法猜测何时会以及何时执行此类转换是不安全的。

因此,您可以自行解决这个问题,这里有一些选择。一种方法是制作也采用该参数模板的函数:

template<T>
void performAction(vector<T> objects) {
  // ...
}

其他人会用(智能)指针替换值 - 他们会轻松处理多态性。

编辑:

为了说明我在最后一句话中的意思:您可以简单地使用 vector< unique_ptr<Parent> >vector< shared_ptr<Parent> > 来存储 Parent 的任何实例(包括 Child),所以您不必对容器进行任何转换。

你可以有一个模板函数 template func(vector vec) { //根据传递的对象类型做一些事情}。向量是对象的容器,因此对于期望向量 &pp 的函数,如果我们传递向量 && cc 将不起作用,代码甚至无法编译。 我们可以使用类似于以下的代码:

class A
{
    int i;
};

class B : public A
{
    int j;
    int k;
};


template<class T> void f(vector<T> &p)
{
    //can handle both types now
}

int main()
{
    B b1;
    A a1;


    vector<A> vectorA;
    vectorA.push_back(a1);

    vector<B> vectorB;  
    vectorB.push_back(b1);

    f<B>(vectorB);

    f<A>(vectorA);
    return 0;
}