在之后仍需要使用源对象时调用父移动分配运算符
Calling parent move assignment operator when source object still needs to be used after
TLDR- 如果是这样,请随时将其标记为重复项;我将删除这个问题。但是,环顾四周后,我什么也找不到。
请考虑以下类:
class Base
{
public:
Base(std::string var1);
Base& operator=(Base&& other) noexcept
{
if (this != &other)
var1_ = std::move(other.var1_);
return *this;
}
protected:
std::string var1_;
};
class Child final : public Base
{
public:
Child(std::string var1, std::string var2);
Child& operator=(Child&& other) noexcept
{
if (this != &other)
{
// Take note of HERE for explanation below
Base::operator=(std::move(other));
var2_ = std::move(other.var2_);
}
}
private:
std::string var2_;
};
这里有两个类,Child
派生自Base
。Child
的成员比Base
多。在Child
的移动赋值运算符中,我们有一个情况,我们有额外的成员也需要分配给other
成员的值。但是,我们首先将other
的内存移动到父移动分配运算符,那么该数据不是无法使用吗?
我想我只是对 (1) 我上面的东西是否真的有什么问题感到困惑,(2) 如果是这样,为什么它会起作用,因为other
应该在使用之前移动,以及 (3) 如果没有,完成我的任务的最佳方法是什么?
更好的方法是先初始化Child
的成员,然后将其交给Base
移动赋值运算符吗?它有什么不同吗?
是的,这是安全的。
首先,请注意,关于不使用移自对象的规则是设计和使用对象的默认准则。这不是语言本身的规则。对于类对象在从中移出后通常保证的内容,包括未另行指定的标准库类类型(例如std::unique_ptr<T>
保证移自指针包含空指针),这是常见的做法。
因此,由于您确切地知道Base::operator=
对other
的作用,并且仅从other.var1_
移动,因此使用other.var2_
仍然是安全的。
这种模式是安全的还有另一个原因,即使你实际上并不确切知道Base::operator=
做什么,或者你想编写Child
代码来继续工作,即使Base
的细节发生了变化。Child
对象包含两个子对象:Base
基类子对象和var2_
成员子对象。这些对象本质上对另一个对象一无所知。(他们可以通过指针、虚函数等手动设置彼此之间的交互,以使事情复杂化,但这种事情应该记录在Base
或Child
中已知)Base::operator=(std::move(other));
语句仅从基类子对象移动,而不是从成员子对象移动,因此成员子对象不受影响,并且Child::operator=(Child&&)
的定义可以安全地防止更改Base
。
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- C++:为什么不调用移动构造函数?
- 为什么这里不调用移动构造函数?
- 为什么不调用移动构造函数
- 为什么调用移动分配?
- 当我将构造函数显式调用为参数时,不会调用移动构造函数
- 为什么只有在向量中已经有一个元素时才调用移动构造函数?
- 如果我们有 (N)RVO,当实际调用移动构造函数时?
- 与移动构造函数混淆:无法调用移动构造函数
- 当设置对象等于另一个函数的返回值时,为什么要调用移动构造函数/分配
- 尚未调用移动构造函数
- emplace_back调用移动构造函数和析构函数
- 为什么要调用移动构造函数
- 为什么在Lambda移动时未调用移动构造函数
- 我应该如何确保对移动构造函数的调用?(移动语义和右值引用)
- 在 c++ 中调用移动构造函数
- 从另一个函数的"if loop"中调用/移动一个函数 - Qt,C++
- 未调用移动赋值运算符
- 为什么不调用移动构造函数?
- 调用移动到Qt中不同线程的QObject函数?