被引用的移动对象

Moving object which is referred

本文关键字:对象 移动 引用      更新时间:2023-10-16

我有两个结构:

struct A
{};
struct B
{
A& a;
};

并将它们初始化A a0; B b{a0};.但是现在,我想将对象移动到新对象a0

A a1{std::move(a0)};

我不知道如何通知b应该更改其成员a的值。不可能更改标准引用的值,因此我想将其更改为std::reference_wrapper或类似的东西。但是仍然存在一个问题 - 如何通知对象b(特别是 - 它的成员现在是某种智能引用)应该更改字段a的值?

我在考虑观察者模式,其中A将成为主体,而B成员指的是A将是观察者。移动主题后,它将向所有观察者发送其新地址。这可能是解决方案,但也许有更简单的东西?


作为附录,为什么我使用这样的东西。在我的项目中,我有另一个结构(下面的简化版本):

struct C
{
A a;
B b{a};
};

A是内存的包装器(指向内存的指针在构造函数中提供给A,但为了保持简单,这里没有提到),它知道分配的内存的大小以及如何写入和读取它。B是知道如何将一些值插入内存的对象(即如何在LEBE中插入int32_t,如何序列化复合对象)。这两个结构位于某个封闭的库中(公司库,所以我可以打开问题来更改它,但它用于其他一些项目,所以我必须确定我需要什么样的更改以及它们是否真的必要)。C为我提供了仅将特定对象放入内存的接口 - 我只获得原始内存来构造它,因此我必须处理创建对象AB它内部和外部C没有人需要知道我使用什么依赖项写入此内存。

结构C应该是可移动的,因为它将使用std::optional返回 - 它的构造函数是私有的,并且存在静态方法create,该方法根据构造它所需的其他一些操作的状态构建C对象(这里简单地使用bool参数描述):

static std::optional<C> create(bool v)
{
return v ? std::optional<C>{C()} : std::optional<C>{};
}

为了测试,我还编写了C的构造函数:

C()
{
std::cout << "C::C()" << std::endl << &a << std::endl << &b.a << std::endl;
}

和尝试构建此对象的函数:

auto c = C::create(true);
std::cout << "main" << std::endl;
std::cout << &(c.value().a) << std::endl;
std::cout << &(c.value().b.a) << std::endl;

以下是执行此测试的结果:

C::C()
0x7ffe8498e560
0x7ffe8498e560
main
0x7ffe8498e570
0x7ffe8498e560

这表明C成员现在b持有错误的引用。

我愿意接受批评,因为我知道这可能是糟糕的设计,也许我应该以其他方式去做。

你的 C 类应该是:

struct C
{
C(const C& c) : a(c.a), b(this->a) {}
C(C&& c) : a(std::move(c.a)), b(this->a) {}
A a;
B b{a};
};

那么您的引用仍然有效。