C++ 被引用的移动对象
我有两个结构:C++ 被引用的移动对象,c++,C++,我有两个结构: struct A {}; struct B { A& a; }; 并初始化它们a0;B{a0}。但现在,我想将objecta0移动到新的: A a1{std::move(a0)}; 我不知道如何通知b它的成员a的值应该更改。无法更改标准引用的值,所以我考虑将其更改为std::reference\u wrapper或类似的内容。但仍然存在一个问题-如何通知对象b(特别是它的成员,现在是某种智能引用)应该更改字段a的值 我在考虑观察者模式,其中A将成为主题,而B
struct A
{};
struct B
{
A& a;
};
并初始化它们a0;B{a0}代码>。但现在,我想将objecta0
移动到新的:
A a1{std::move(a0)};
我不知道如何通知b
它的成员a
的值应该更改。无法更改标准引用的值,所以我考虑将其更改为std::reference\u wrapper
或类似的内容。但仍然存在一个问题-如何通知对象b
(特别是它的成员,现在是某种智能引用)应该更改字段a
的值
我在考虑观察者模式,其中A
将成为主题,而B
引用A
的成员将成为观察者。移动主题后,它将向所有观察者发送其新地址。这可能是一个解决办法,但也许有更简单的办法
作为附录,我为什么要用这样的东西。在我的项目中,我有另一个结构(简化版本如下):
A
是内存的包装器(在构造函数中,指向内存的指针被赋予A
,但这里没有提及以保持它的简单性),它知道分配内存的大小以及如何写入和读取它B
是知道如何将一些值插入内存的对象(即如何插入int32_t
-在LE或BE中,如何序列化复合对象)。这两个结构都在某个封闭的库中(公司库,所以我可以打开问题来更改它,但它在其他一些项目中使用,所以我必须确定我需要什么样的更改,以及它们是否真的有必要)C
为我提供了只将特定对象放入内存的接口-我只获得原始内存来构造它,因此我必须处理创建对象A
和B
在它内部和外部C
没有人需要知道我使用哪些依赖项写入这个内存
结构C
应该是可移动的,因为它将使用std::optional
返回-它的构造函数是私有的,并且存在静态方法create
,该方法根据构建C
对象所需的一些其他操作的状态来构建对象(此处仅使用bool
参数进行描述):
和尝试构建此对象的函数:
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
成员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};
};
那么您的引用仍然有效。修复您的C
move/copy构造函数。默认值不是您想要的值。看起来您不应该使用引用,以防以后移动它,因为我理解您问题的核心是:“无法更改标准引用的值”…引用的值“是它引用的变量的值,这就是它引用变量的方式work@user463035818也许这是一条太大的捷径,我一直认为不可能改变所引用的变量,它总是指向同一个变量。正因为如此,我在考虑一些明智的参考。但仍然存在如何通知它的问题,关于移动引用的变量,它只需很少的示例,但在B
不是那么简单的情况下,它将失去状态,因为它将被重建,而不是移动。@3mbd3v您可以编写aB::B(B&&,a&)
,这将旧的B
状态转移到新的B
@Caleth,我想这就是我要寻找的灵魂。它需要对实现B
的库进行一些更改,但这是最简单的解决方案。
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
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};
};