简体   繁体   English

引用派生 class 指针的 std::vector 作为 function 的输入参数

[英]reference to a std::vector of derived class pointers as input parameter to a function

First of all I'd like to apologize if there's another question like this one and I didn't find it.首先,如果还有其他类似的问题,我想道歉,但我没有找到它。 I've been trying but since the problem is quite specific I couldn't find one.我一直在尝试,但由于问题非常具体,我找不到。

Now, the problem.现在,问题。 I have a Base class and a Derived class (say BNode and DNode ), and I have a std::vector of BNode*.我有一个 Base class 和一个 Derived class (比如 BNode 和 DNode ),我有一个 std::vector 的 BNode*。 I have also a function which receives a reference to a vector of these pointers.我还有一个 function 接收对这些指针向量的引用。 I'm having trouble when trying to pass a std::vector of pointers to derived objects as a parameter to this function:我在尝试将指向派生对象的指针的 std::vector 作为参数传递给此 function 时遇到问题:

class BNode
{
};

class DNode : public BNode
{
};

class Other
{
function(std::vector<BNode*>& inputVector) { } 
}

When trying to pass a vector of pointers to the derived class, the error I'm receiving from VS is:当试图将指针向量传递给派生的 class 时,我从 VS 收到的错误是:

1> error C2664: 'Other::function' : cannot convert parameter 1 'std::vector<T>' to 'std::vector<T> &'
1>        with
1>        [
1>            T=DNode *
1>        ]
1>        and
1>        [
1>            T=BNode *
1>        ]

Thanks beforehand.预先感谢。

Your problem is that even if DNode derives from BNode , std::vector<DNode*> doesn't derive from std::vector<BNode*> . 您的问题是,即使DNodeBNode派生, std::vector<DNode*>也不从std::vector<BNode*>派生。

Therefore, the compiler does not know how to convert from one type to the other. 因此,编译器不知道如何从一种类型转换为另一种类型。

You might however do: 但是,您可以这样做:

std::vector<BNode*> bnode_list;
std::vector<DNode*> dnode_list(bnode_list.begin(), bnode_list.end());

This is because vector< Bnode* > and vector< Dnode* > do not have any parent-child relation. 这是因为vector <Bnode *>和vector <Dnode *>没有任何父子关系。 They are different objects. 它们是不同的对象。

I guess you have created a vector like std::vector< DNode* > dnodevec; 我猜您已经创建了一个像std :: vector <DNode *> dnodevec的矢量; Instead you can create std::vector< BNode* > dnodevec; 相反,您可以创建std :: vector <BNode *> dnodevec;。 Being the vector of base class pointers you can safely insert any DNode type pointer in the vector. 作为基类指针的向量,您可以安全地在向量中插入任何DNode类型的指针。

I suspect you are probably calling Other::function something like this: 我怀疑您可能正在调用Other::function东西:

std::vector<DNode *> v;
// put stuff into v
Other o;
o.function(v);

Which won't compile, as std::vector<DNode *> is a distinct type to std::vector<BNode *> . 不会编译的std::vector<DNode *>std::vector<BNode *>的独特类型。

What may be suitable is: 可能合适的是:

std::vector<BNode *> v;
// You can put DNode * items into v
Other o;
o.function(v);

Unfortunately, what you want is not possible in C++, because vector<BNode*> and vector<DNode*> are considered to be unrelated types (even though there is a clear relation between BNode and DNode ). 不幸的是,您想要的东西在C ++中是不可能的,因为vector<BNode*>vector<DNode*>被认为是不相关的类型(即使BNodeDNode之间有明确的关系)。

Consider the following code: 考虑以下代码:

class BNode
{
};

class DNode : public BNode
{
};

class XNode : public BNode
{
};

void function(std::vector<BNode*>& inputVector) 
{
  inputVector.push_back(new XNode); // This will work, as XNode derived from BNode
} 

int main()
{
  std::vector<DNode*> vec;

  function(vec); // Suppose this would work
  // Then now, vec would contain a pointer to the unrelated class XNode!!
}

C++ doesn't support covariance in templates. C ++在模板中不支持协方差 An std::vector<DNode*> cannot be assigned to an std::vector<BNode*> even if DNode derives from BNode . 即使DNodeBNode派生,也无法将std::vector<DNode*>分配给std::vector<BNode*>

For your code to work, you should only declare vectors of pointers to BNode and populate them with pointers to DNode as needed. 为了使代码正常工作,您仅应声明指向BNode的指针向量,并根据需要使用指向DNode的指针填充它们。

std::vector is not covariant . std::vector不是协变的

In general, you should not pass a vector of DNode * as a vector of BNode * . 通常,不应将DNode *的向量传递为BNode *的向量。 If function adds or replaces pointers to a subclass of BNode different from DNode , you would get non- DNode pointers in your DNode * vector. 如果function添加或替换指向不同于DNodeBNode子类的指针,则将在DNode *向量中获得非DNode指针。

You better change your types as explained in the other answers. 您最好按照其他答案中的说明更改类型。

But contrary to what other answers say, it is possible to pass a vector of DNode * if function only reads the vector. 但是与其他答案相反,如果function仅读取向量, 可以传递DNode *的向量。 To mark it so, change its signature to accept a const reference. 为此,请更改其签名以接受const引用。 Then you can pass your DNode * vector as follows: 然后,您可以按以下方式传递DNode *向量:

function(reinterpret_cast<const std::vector<BNode *> &>(vec));

reinterpret_cast is generally dangerous and you should avoid it unless you know very well what you are doing. reinterpret_cast通常很危险,应该避免使用它,除非您非常了解自己在做什么。 Here, you are circumventing the C++ type system to treat a vector of DNode * as a vector of BNode * . 在这里,您正在规避C ++类型系统,将DNode *的向量BNode *的向量。 Raw pointers are primitive types with the same binary representation regardless of the pointed-to type. 原始指针是具有相同二进制表示形式的原始类型,而与指向类型无关。 Therefore the vectors of both pointer types are runtime compatible. 因此,两种指针类型的向量都是运行时兼容的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使指向基类指针std :: vector的指针指向派生类指针的std :: vector - Making a pointer to std::vector of base class pointers point to std::vector of derived class pointers 如何在指向基类对象的指针向量中引用派生对象? - How to reference derived objects in a vector of pointers to base class objects? 在function参数中的向量中传递两个派生的class - Pass two derived class in a vector in function parameter 提升指针 std::vector 的序列化。 错误:“未注册的类 - 未注册或导出派生类” - Boost serialization of a std::vector of pointers. Error: "unregistered class - derived class not registered or exported" 类指针向量上的std :: sort() - std::sort() on a vector of Class pointers 指向矢量的基类在派生类中 - Vector of pointers to base class within a derived class 将指向派生类实例的指针存储在std :: map中 - storing pointers to derived class instances in a std::map 通过引用基类作为参数的函数传递派生类 - Passing derived class by reference to function taking base class as parameter 深度复制派生的指针向量 class - Deep copying a vector of pointers in derived class 将派生类指针的矢量传递给线程 - Pass vector of derived class pointers to thread
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM