我有一堂课:
template<class T>
class IdRange
{
T var1_;
...
T var6_;
T start_;
T step_;
public:
IdRange(T start = 0, T step = 1) { ... }
IdRange(IdRange&& other)
: var1_ (std::move(other.var1_)),
...
var6_ (std::move(other.var6_)),
start_(std::move(other.start_)),
step_ (std::move(other.step_))
{
Как сделать здесь?
}
}
(通过“覆盖”我的意思是分配一个默认值。这么短。)
情况是这样的。有不同的字段,我将它们指定为T var1_; ... T var6_;. 一切都很清楚,我将它们从other转移到this并在other中覆盖它们,但也有start_和step_。首先,他们也应该像其他人一样被转移。但那该怎么办呢。start_和step_仅在创建对象时设置,之后无法更改。在这种情况下该怎么办:
- 覆盖其他字段,但不要覆盖start_和step_。
- 擦拭一切。
- 因此,对此没有任何规定,您可以随心所欲。
和一点澄清。
IdRange(IdRange&& other)
: var1_ (std::move(other.var1_)),
...
var6_ (std::move(other.var6_)),
start_(std::move(other.start_)),
step_ (std::move(other.step_))
}
值得写std::move吗?我不去哪个站点,这里没有人使用它们,没有它们,就会调用复制构造函数,因此调试器会显示是否有任何内容。
移动对象时,只需要在想要摆脱双重所有权问题时覆盖边距。例如,作为指针的字段指向分配的内存区域。并且当调用一个析构函数时,第二个对象将被剥夺数据,第二次删除内存将导致内存错误。
这一切都取决于算法和场的原理。可能存在整数索引可以用作某些内存区域所有权的标志的选项。然后这些索引应该被重置为零,这样就没有双重所有权。
该命令
std::move是类型转换的简化static_cast<C&&>(..)。如果内部变量的值应该转移到另一个对象,则应该使用它。但是当调用移动构造函数时,简单类型通常不会无效,程序员应该手动执行此操作。带指针的示例:
如果您有一个具有模板化内部类型的类,您应该使用
std::move通用行为,并且如果在简单类型(例如指针)上调用移动构造函数,则从外部内存源的所有权手动调用清理函数。粗略地说,有两种类:
有些需要自定义析构函数来复制和/或移动构造函数和赋值运算符,因为它们直接拥有某些资源(或其他原因)。
谁不需要这些,他们不拥有任何东西。
大多数是后者。
在您的课程中,我没有在移动构造函数中看到任何特殊逻辑,因此您可能应该遵循零规则,而不是编写移动构造函数或其他列出的操作。
这将导致它们被移动的对象的字段不会被清空,这对于第二类的类是正常的。您不会为每个小结构手动编写所有 5 个操作来实现此归零。
第一类中的类通常需要取消所有内容(或做类似的事情)。想象一下,如果
std::vector在移动时,指向缓冲区的指针会归零(没有这个,无论如何),但大小不会。这会很糟糕。