#include <iostream>
#include <vector>
#include <string>
struct A
{
std::string a;
std::vector<A> avector;
};
typedef std::vector<A> Avector;
A& func(A& x)
{
A& ret = x.avector[0];
return ret;
}
int main()
{
A genesis = { "Parent", std::vector<A>() };
A l1 = { "Child1", std::vector<A>() };
A l2 = { "Child2", std::vector<A>() };
genesis.avector.push_back(l1);
genesis.avector.push_back(l2);
std::cout << "l1: " << l1.a << std::endl; //shows "Child1"
std::cout << "l2: " << l2.a << std::endl; //shows "Child2"
A& lx = func(genesis);
lx.a = "Childx";
std::cout << "l1: " << l1.a << std::endl; //!!still shows "Child1"
return 1;
}
因此,基本上我想要的是整体具有单个数据副本,即Genesis对象以及另外两个对象l1和l2作为Genesis的对象。
但是,由于每次我最终修改副本而不是Genesis对象下的实际数据时,我都无法修改它。
谢谢你的帮助!
最佳答案
在您的代码中:
A genesis = { "Parent", std::vector<A>() };
A l1 = { "Child1", std::vector<A>() };
A l2 = { "Child2", std::vector<A>() };
genesis .avector.push_back(l1);
genesis .avector.push_back(l2);
您有5个实例。您声明的3个和载体中的2个副本。
因此,更正确(但可能有错误)的方法是:
A genesis = { "Parent", std::vector<A>() };
genesis .avector.emplace_back("Child1", std::vector<A>());
genesis .avector.emplace_back("Child2", std::vector<A>());
A& l1 = genesis.avector[0];
A& l2 = genesis.avector[1];
现在您只有3个实例。 l1和l2是对向量中项目的引用,因此对它们的更改也将重新纳入向量中。
我说这可能是越野车。当您更改向量(添加其他内容)时,向量可能不得不重新分配,因此您拥有的所有引用都将无效,结果是未定义的行为。
如果确实需要修改向量,则可以执行
vector<unique_ptr<A>>
。然后A& l1 = *genesis.avector[0]
,它将保持有效,直到从矢量中删除该项目为止。如果希望对象驻留在堆栈中,也可以尝试使用
std::reference_wrapper
代替unique_ptr
。我会尽量避免这种情况,因为从向量中擦除时,与局部变量超出范围时相比,很明显会破坏某些东西。