【发布时间】:2020-06-12 03:25:57
【问题描述】:
在这里,我有一个非常简单的程序,可以将值从一个对象移动到另一个对象,确保从获取它的对象中删除该值(留下“0”)。
#include <iostream>
struct S
{
S(char val) : m_val(val) {}
S& operator=(S&& other) noexcept
{
this->m_val = other.m_val;
other.m_val = '0';
return *this;
}
char m_val = '0';
};
int main()
{
S a('a');
S b('b');
std::cout << "a.m_val = '" << a.m_val << "'" << std::endl;
std::cout << "b.m_val = '" << b.m_val << "'" << std::endl;
a = std::move(b);
std::cout << "a.m_val = '" << a.m_val << "'" << std::endl;
std::cout << "b.m_val = '" << b.m_val << "'" << std::endl;
return 0;
}
正如所料,这个程序的输出是:
a.m_val = 'a'
b.m_val = 'b'
a.m_val = 'b'
b.m_val = '0'
'b' 的值从对象 b 转移到对象 a,留下一个 '0'。 现在,如果我用一个模板(希望)自动执行移动和删除业务来概括这一点,这就是我最终得到的......(当然是精简的)。
#include <iostream>
template<typename T>
struct P
{
P<T>& operator=(P<T>&& other) noexcept
{
T& thisDerived = static_cast<T&>(*this);
T& otherDerived = static_cast<T&>(other);
thisDerived = otherDerived;
otherDerived.m_val = '0';
return *this;
}
protected:
P<T>& operator=(const P<T>& other) = default;
};
struct S : public P<S>
{
S(char val) : m_val(val) {}
char m_val = '0';
};
int main()
{
S a('a');
S b('b');
std::cout << "a.m_val = '" << a.m_val << "'" << std::endl;
std::cout << "b.m_val = '" << b.m_val << "'" << std::endl;
a = std::move(b);
std::cout << "a.m_val = '" << a.m_val << "'" << std::endl;
std::cout << "b.m_val = '" << b.m_val << "'" << std::endl;
return 0;
}
运行时,输出为:
a.m_val = 'a'
b.m_val = 'b'
a.m_val = '0'
b.m_val = '0'
哦哦!不知何故,两个对象都被“删除”了。当我逐步浏览移动赋值运算符代码的主体时......一切似乎都很好! a.m_val 是 'b' 就像我们期望的那样......直到 return *this; 声明。一旦它从函数返回,这个值突然被设置回“0”。
谁能解释一下为什么会这样?
【问题讨论】:
标签: c++ templates variable-assignment operator-keyword stdmove