我有这个:
std::vector <BinaryTree*> children;
其中BinaryTree
是一个类。如何在此向量中添加元素?
我尝试了children.push_back(X)
,其中X
是该类的一个实例,但它给了我这个错误:
无法将参数1从“BinaryTree”转换为“BinaryTree *&amp;&amp;”
答案 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 );
现在您不必担心在清空向量之前删除对象。