我试图找出最佳方法来保存指向刚刚创建并添加到成员变量向量的向量中元素的指针:
SceneGraphNode* addChild(std::string name){
SceneGraphNode child(this,name);
m_children.push_back(child);
return &child;
}
编译器正确地给了我一个警告,因为我返回了在堆栈上创建的对象的地址,并且该对象将在函数结束时超出范围。但是,对象存在于vector
,对吗?
那么,我应该忽略这个警告还是有更好的方法来做到这一点?
答案 0 :(得分:11)
但是,对象存在于向量中,对吗?
不,它的副本确实如此。您想要返回副本的地址。
return &m_children.back();
但是,存储指向驻留在向量中的对象的指针并不是一个好主意。因为当向量需要重新分配时,指针将失效。也许你应该在你的向量中存储指针(最好是智能指针)。
例如:
// in your class
std::vector<std::unique_ptr<SceneGraphNode>> m_children;
SceneGraphNode* addChild(std::string name)
{
std::unique_ptr<SceneGraphNode> child(new SceneGraphNode(this,name));
m_children.push_back(std::move(child));
return m_children.back().get();
}
答案 1 :(得分:0)
但是,对象存在于向量中,对吗?
当你推入向量时,它实际上将copies
对象而不是对象本身推送到向量中。 STL容器执行copy in, copy out
。但是,如编译器所示,您不应该return the address of an object created on the stack
。
答案 2 :(得分:0)
将它添加到std :: vector时,你实际上是在做一个副本。您应该返回对向量中存储的对象的引用。
return &(m_children.back());
答案 3 :(得分:0)
对象并不完全存在于向量中,因为当你push_back
它时,你正在制作这个元素的副本。
如果您通过类似的方式更改返回,此代码可以正常工作(Ryan的形式实际上会更直接):
return &m_children[m_children.size() - 1];
这样,你就可以有效地返回指向生成在向量中的元素的指针。