#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
我会尽量避免这种情况,因为从向量中擦除时,与局部变量超出范围时相比,很明显会破坏某些东西。

10-04 14:39