Dra*_*son 1 c++ memory inheritance move-semantics
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_;
};
Run Code Online (Sandbox Code Playgroud)
这里有两个类,Child
从Base
. Child
拥有比 多的成员Base
。在 的移动赋值运算符中Child
,我们有一种情况,我们有额外的成员,这些成员也需要分配给other
的成员的值。但是,我们首先将 的内存移动other
到父移动赋值运算符,那么该数据不会不可用吗?
我想我只是对(1)我上面的内容是否真的有任何问题感到困惑,(2)如果是这样,为什么它可以工作,因为other
它应该在使用之前被移动,以及(3)如果没有,完成我所拥有的任务的最佳方法是什么?
更好的方法是简单地初始化Child
first的成员,然后将其交给Base
移动赋值运算符?这有什么不同吗?
是的,这是安全的。
首先,请注意不使用移动对象的规则是设计和使用对象的默认准则。这不是语言本身的规则。这是类对象在移出后通常保证的常见做法,包括没有另外指定的标准库类类型(例如std::unique_ptr<T>
保证移出的指针持有空指针)。
因此,既然您确切地知道Base::operator=
to 的作用other
,并且只从 移动other.var1_
,那么使用 仍然是安全的other.var2_
。
这种模式是安全的还有另一个原因,即使您实际上Base::operator=
并不确切知道它的作用,或者您想编写Child
代码以保持工作,即使细节发生Base
变化。一个Child
对象包含两个子对象:Base
基类子对象和var2_
成员子对象。这些对象本质上并不知道其他对象的任何信息。(他们可以通过指针,虚函数等已经手动建立互动对方,到复杂的东西,但那种事情应该记录的Base
或已知Child
)的Base::operator=(std::move(other));
正好从基类子对象的语句移动,而不是从成员子对象,因此成员子对象不受影响,并且 的定义不会Child::operator=(Child&&)
对 进行更改Base
。
归档时间: |
|
查看次数: |
43 次 |
最近记录: |