尝试从 Derived* 的向量中分配 Base* 的向量

2021-12-21 00:00:00 inheritance pointers vector c++

这似乎是一个非常基本的问题,但我无法弄清楚.我有一个 std::vector 指向派生对象的原始指针,我只想使用赋值运算符将它复制到另一个 Base 指针向量.使用 VC++ 我得到错误 C2679二进制'=:没有找到运算符..."顺便说一句,我不想??复制对象的深层副本,我只想复制指针.示例代码:

This seems like a pretty basic problem, but I can't figure it out. I have a std::vector of raw pointers to Derived objects, and I just want to copy it to another vector of Base pointers using the assignment operator. With VC++ I get error C2679 "binary '=': no operator found..." BTW I don't want a deep copy of the objects, I just want to copy the pointers. Sample code:

#include <vector>
using namespace std;

struct Base{};    
struct Derived: public Base {};

int main (int argc, char* argv[])
{
    vector<Derived*> V1;
    vector<Base*> V2;
    V2 = V1;  //Compiler error here
    return 0;
}

令我困惑的是,我可以通过循环遍历向量并使用 push_back 来复制向量,如下所示:

What confuses me is that I can copy the vector by looping through it and using push_back, like this:

for (Derived* p_derived : V1)
    V2.push_back(p_derived);

所以我的问题是为什么分配失败,而 push_back 有效?对我来说似乎是一样的.

So my question is why does the assignment fail, while push_back works? Seems like the same thing to me.

推荐答案

那是因为 BaseDerived 有关系,vector< 没有关系;Base*>vector.就类层次结构而言,它们完全不相关,因此您不能将一个分配给另一个.

That's because while Base and Derived have a relationship, there is no relationship between vector<Base*> and vector<Derived*>. As far as class hierarchy is concerned, they are entirely unrelated, so you can't assign one to the other.

您正在寻找的概念称为协方差.例如,在 Java 中,String[]Object[] 的子类型.但是在 C++ 中,这两种类型只是不同的类型,与 String[]Bar 没有什么关系.

The concept you are looking for is called covariance. In Java for instance, String[] is a subtype of Object[]. But in C++, these two types are just different types and are no more related than String[] and Bar.

push_back 有效,因为该方法只需要一个 T const&(或 T&&),所以任何可以转换为 Base* 是可以接受的 - Derived* 是.

push_back works because that method just takes a T const& (or T&&), so anything convertible to a Base* will be acceptable - which a Derived* is.

也就是说,vector 有一个带有一对迭代器的构造函数,在这里应该更容易使用:

That said, vector has a constructor that takes a pair of iterators, which should be easier to use here:

vector<Base*> v2(v1.begin(), v1.end());

或者,因为它已经构建:

Or, since it is already constructed:

v2.assign(v1.begin(), v1.end());

相关文章