【问题标题】:std::find for vector containing pointersstd::find 查找包含指针的向量
【发布时间】:2014-03-31 11:09:42
【问题描述】:

我有一个类 Node 和一个派生类 ChildNode,如下所示

#include<iostream>
using namespace std;
class Node
{
public:
    int nodeId;
    bool operator==(int id) const { return (this->nodeId ==id);}; //used in STL Find function
    Node(int id)
    {
        this->nodeId=id;
    }
    ~Node(void)
    {
    }
    virtual void SaySomeThing()
    {
        cout<<"Hey! I am node"<<endl;
    }
};
class ChildNode:public Node
{
public:
    ChildNode(int id):Node(id){};
    virtual void SaySomeThing()
    {
        cout<<"Hey! I am a child node"<<endl;
    }
};

现在我主要调用 NodeVectorTest 方法,该方法具有包含节点的向量对象

void NodeVectorTest()
{
    vector<Node> nodes;
    Node *node=new Node(22);
    nodes.push_back(*node);
    delete node;
    node=new ChildNode(23);
    nodes.push_back(*node);
    delete node;
    node=new Node(33);
    nodes.push_back(*node);
    delete node;

    //Find node
    vector<Node>::iterator nodePosition;
    int nodeId=23;
    nodePosition =find(nodes.begin(),nodes.end(),nodeId);
    if(nodePosition == nodes.end()) { ///we didnt find the node id ..

        cerr<<"node id "<< nodeId <<" Could not be found "<<endl;

        return ;
    }

    else{ //now we have the right node to do our desired stuff
        (*nodePosition).SaySomeThing();
    }
}

当我找到节点 23 时,它被转换为 Node 对象而不是 Node*,因此它显示输出为 Hey! I am node 以实现多态性,我将这个 vector&lt;Node&gt; nodes; 转换为 vector&lt;Node*&gt; nodes;,如下代码所示

vector<Node*> nodes;
Node *node=new Node(22);
nodes.push_back(node);
node=new ChildNode(23);
nodes.push_back(node);
node=new Node(33);
nodes.push_back(node);

//Find node
vector<Node*>::iterator nodePosition;
int nodeId=23;
nodePosition =find(nodes.begin(),nodes.end(),nodeId);

if(nodePosition == nodes.end()) { ///we didnt find the node id ..

    cerr<<"node id "<< nodeId <<" Could not be found "<<endl;

    return ;
}

else{ //now we have the right node to do our desired stuff
    (*nodePosition).SaySomeThing();
}

当我把它改成这个时,我得到了以下错误

错误 1 ​​错误 C2446: '==' : 没有从 'const int' 转换为 'Node *' microsoft visual studio 11.0\vc\include\xutility
错误 2 错误 C2040: '==' : 'Node *' 与 'const int' microsoft visual studio 11.0\vc\include\xutility 的间接级别不同

在这方面有什么帮助吗?

【问题讨论】:

  • 非叶子类应该是抽象的;这条简单的指导方针会让您省去很多麻烦。
  • 您可能希望将构造函数标记为 explicit,因为目前您可以直接将 int 分配给 Node 实例,这似乎不是一个好主意。
  • @ArneMertz,没有这样的东西。我先推送它,它将创建另一个节点对象,然后我正在删除,所以没有未定义的行为。如果有类似的事情请赐教。问候
  • @Zaksh 抱歉,我有点误读了这些示例 - 那么这是另一个问题:在 NodeVectorTest 中,您不必要地在免费商店而不是堆栈上创建 Nodes。整个new-delete 狂欢毫无用处,而且会不必要地减慢您的程序速度。
  • @zaksh 考虑std::vector&lt;std::unique_ptr&lt;Node&gt;&gt;

标签: c++ c++11 vector stl polymorphism


【解决方案1】:

nodes 的元素是指向Node指针,而不是Node。所以,你应该使用std::find_if

nodePosition = find_if(nodes.begin(), nodes.end(),
    [nodeId](Node *p) { return *p == nodeId; });

PS。尽管c++11 是您问题的标签,但您没有使用C++11 的任何好功能!

PS2。请注意您的第一个 vector&lt;Node&gt; 示例将出现切片问题

PS3。在您的第一个示例中,您不需要也不应该使用new。只需nodes.push_back(Node(22));nodes.emplace_back(22);

【讨论】:

  • 不应该是find_if吗?
  • 谢谢@ikh,这正是我所需要的。我尝试了 find_if,但无法弄清楚如何在我的场景中使用它。
【解决方案2】:

请注意,默认情况下find 将使用operator== 将一个对象与另一个相同类型的对象进行比较。在这种情况下,您需要重载 bool operator==(const Node*, const Node*),这是不可能的。一个更好的选择是使用带有谓词的 find,它在函数 std::find_if 中实现。

【讨论】:

  • 如果没有一个操作数是 UDT,则不能重载运算符。指针被视为 UDT,因此重载 operator=(Node const*, Node const*) 不仅不明智,而且是不可能的。
  • @ArneMertz 很公平。我已经修正了我的措辞。谢谢
猜你喜欢
  • 1970-01-01
  • 2018-08-28
  • 2018-10-09
  • 2018-06-10
  • 1970-01-01
  • 2018-05-30
  • 1970-01-01
  • 2015-12-05
  • 1970-01-01
相关资源
最近更新 更多