4

我有这个:

std::vector <BinaryTree*> children;

在哪里BinaryTree上课。如何将元素添加到此向量中?

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

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

4

8 回答 8

11

只需使用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

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

std::vector<BinaryTree> children;
BinaryTree tree;
children.push_back(tree);
于 2013-03-12T21:11:27.157 回答
3

*从模板参数中省略星号:

std::vector<BinaryTree> children;

您希望孩子保存数据,而无需像new BinaryTree.

于 2013-03-12T21:11:29.873 回答
3

这实际上取决于谁应该拥有指针。在最简单的情况下,向量不拥有它们,那么您传递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;
于 2013-03-12T21:11:42.790 回答
1
std::vector<SomeObject*> objectVector;
objectVector.push_back(new SomeObject());

我是怎么做的。

于 2013-03-12T21:11:19.247 回答
0

你有指针向量:

std::vector <BinaryTree*> children;

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

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

在做这样的事情时要小心:

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

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

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

于 2013-03-12T21:11:36.430 回答
0
children.push_back(&X);

这将起作用,但请记住,一旦您的对象离开范围,它的删除器将被调用,您将得到一个无效的指针。

于 2013-03-12T21:11:57.703 回答
0
children.push_back(&X);

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

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

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

于 2013-03-12T21:12:44.367 回答
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 );

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

于 2013-03-12T21:16:01.147 回答