gpt4 book ai didi

c++ - `*this` 可以是 `move()` d 吗?

转载 作者:IT老高 更新时间:2023-10-28 21:46:35 24 4
gpt4 key购买 nike

我想定义一个用于编码数据的类;编码完成后,我想将编码的数据从其中 move 移出,这可能会使编码对象无效。

我相信这可以通过下面的static函数extractData实现:

class Marshaller
{
public:
static DataType extractData(Marshaller&& marshaller)
{
return std::move(marshaller.data);
}
private:
DataType data;
}

虽然这样调用有点不方便:

Marshaller marshaller;
// ... do some marshalling...
DataType marshalled_data{Marshaller::extractData(std::move(marshaller))};

那么我可以用成员函数包装它吗?

DataType Marshaller::toDataType()
{
return Marshaller::extractData(std::move(*this));
}

当然,这会被调用:

DataType marshalled_data{marshaller.toDataType()};

...对我来说,这看起来好多了。但是 std::move(*this) 的事情看起来非常可疑。在调用 toDataType() 的上下文中,marshaller 不能再使用了,但我认为编译器无法知道:函数体可能在调用者的编译单元之外,因此没有任何迹象表明 marshaller 已经应用了 move()

这是未定义的行为吗?完全没问题吗?或者介于两者之间?有没有更好的方法来实现相同的目标,最好不使用宏或要求调用者显式 move marshaller

编辑: 使用 G++ 和 Clang++,我发现我不仅可以编译上述用例,而且实际上我可以继续通过编码器对基础数据进行修改,然后使用 toDataType 函数重新提取修改后的数据。我还发现marshalled_data中的already-extracted数据继续被marshaller改变,说明marshalled_datamarshaller 和调用上下文之间共享,所以我怀疑这里存在内存泄漏或未定义的行为(来自双重删除)。

编辑 2: 如果我在 DataType 的析构函数中放入 print 语句,当调用者离开作用域时,它会出现 两次。如果我在 DataType 中包含一个数据成员,其中包含一个数组,并带有相应的 new[]delete[],我会得到一个glibc “双重释放或损坏”错误。所以我不确定这如何是安全的,尽管有几个答案说它在技术上是允许的。一个完整的答案应该解释正确使用这种技术与非平凡的 DataType 类需要什么。

编辑 3: 我打开的兔子洞/蠕虫 jar 头就够了 another question解决我剩下的问题。

最佳答案

根据标准,move-from 对象仍然有效,尽管不能保证其状态,因此从 *this move 似乎是完全有效的。代码的用户是否会感到困惑完全是另一个问题。

这听起来像您的真实意图是将编码(marshal)的破坏与数据的提取联系起来。您是否考虑过在一个表达式中完成所有编码并让临时人员为您处理事情?

class Marshaller
{
public:
Marshaller& operator()(input_data data) { marshall(data); return *this; }
DataType operator()() { return std::move(data_); }
private:
DataType data_;
}

DataType my_result = Marshaller()(data1)(data2)(data3)();

关于c++ - `*this` 可以是 `move()` d 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29504070/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com