如何在指针向量中添加元素?

时间:2013-03-12 21:09:03

标签: c++ pointers vector

我有这个:

  

std::vector <BinaryTree*> children;

其中BinaryTree是一个类。如何在此向量中添加元素?

我尝试了children.push_back(X),其中X是该类的一个实例,但它给了我这个错误:

  

无法将参数1从“BinaryTree”转换为“BinaryTree *&amp;&amp;”

8 个答案:

答案 0 :(得分:10)

只需使用push_back()并将指针传递给BinaryTree的实例:

std::vector <BinaryTree*> children;
BinaryTree* pTree = new BinaryTree();
children.push_back(pTree);
...
delete pTree;

为了避免手动内存管理,如果需要引用语义,请使用智能指针而不是原始指针:

#include <memory> // For std::shared_ptr

std::vector <std::shared_ptr<BinaryTree>> children;
std::shared_ptr<BinaryTree> pTree = std::make_shared<BinaryTree>();
children.push_back(pTree);
...
// No need to delete pTree

std::shared_ptr<>类模板是C ++ 11标准库的一部分。在C ++ 03中,您可以使用(几乎)等效的boost::shared_ptr<>

#include <boost/shared_ptr.hpp> // For std::shared_ptr

std::vector <boost::shared_ptr<BinaryTree>> children;
boost::shared_ptr<BinaryTree> pTree = boost::make_shared<BinaryTree>();
children.push_back(pTree);
...
// No need to delete pTree

最后,如果您根本不需要引用语义并希望将二进制树视为值,您甚至可以考虑定义std::vector<BinaryTree>

std::vector<BinaryTree> children;
BinaryTree tree;
children.push_back(tree);

答案 1 :(得分:3)

从模板参数中删除星号*

std::vector<BinaryTree> children;

您希望孩子保留数据,而不需要new BinaryTree中的手动/动态内存分配。

答案 2 :(得分:2)

这实际上取决于谁应该拥有指针。在最简单的情况下,向量不拥有它们,然后传递BinaryTree对象的地址。

BinaryTree b = ...;
children.push_back(&b);

但你必须确保b至少与children一样长。

如果向量拥有指针,那么你应该存储智能指针以避免必须处理内存管理:

std::vector<std::unique_ptr<BinaryTree>> children;
children.push_back(std::unique_ptr<BinaryTree>(new BinaryTree(args)));

如果您不知道所有这些“所有权”业务的含义,那么您最好使用简单的对象向量:

std::vector<BinaryTree> children;

答案 3 :(得分:1)

std::vector<SomeObject*> objectVector;
objectVector.push_back(new SomeObject());

我是怎么做的。

答案 4 :(得分:0)

你有指针的矢量:

std::vector <BinaryTree*> children;

所以添加元素的正确方法是:

BinaryTree* child = new BinaryTree();
children.push_back(child);

做这样的事情时要小心:

{
    BinaryTree child;
    children.push_back(&child);
}

因为这样一个元素的生命周期可能比向量的生命周期短,你可能最终会尝试访问一个不再存在的元素(悬空指针),这会产生未定义的行为。完成后也不要忘记delete这些元素。

但是考虑首先使用对象向量(即std::vector<BinaryTree>)总是好的,因为这会为你处理那种难看的内存管理。

答案 5 :(得分:0)

children.push_back(&X);

这将有效,但请记住,一旦你的对象离开作用域,它的删除器将被调用,你将留下一个无效的指针。

答案 6 :(得分:0)

children.push_back(&X);

传递地址,就像使用它作为指针一样。但问题是,如果该实例超出范围,那么最好这样做

BinaryTree* X = new BinaryTree;
children.push_back(X);

这将确保X永远不会超出范围,但是当你完成它时你必须手动删除它。

答案 7 :(得分:0)

vector包含指向类型BinaryTree对象的指针。你需要

BinaryTree bt;
children.push_back( &bt );

但是你必须确保bt对象的生命周期至少与vector的生命周期相匹配。

你可能想要这个

children.push_back( new BinaryTree );

但在这种情况下,您必须在delete中包含的指针上调用vector以防止内存泄漏。

很明显,这两种选择都不容易管理。一个简单的改变是让容器按值存储元素。

std::vector<BinaryTree> children;
BinaryTree bt;
children.push_back( bt );

如果你必须存储指针,请使用智能指针来代替它们。

std::vector<std::unique_ptr<BinaryTree>> children;
children.push_back( new BinaryTree );

现在您不必担心在清空向量之前删除对象。