我的移动赋值运算符遇到了一些麻烦,也许我只是误解了发生的事情。我下面的SignalHolder
对象意味着保存一个指向Signal
对象的共享指针,并在SignalHolder被销毁后立即调用其detach()
方法。由于破坏对象会自动导致信号中断,因此只存在一个对象是很重要的。因此,我使用move语义来确保只存在一个。
*this
和c
都指向同一个对象。我认为std::move
应该将shared_ptr移动到*this
,并将c
与nullptr一起留下?我哪里做错了?class SignalHolder
{
std::shared_ptr<SignalCallbackBase> _target;
inline static int idIdx = 0;
int id;
public:
SignalHolder(std::shared_ptr<SignalCallbackBase> target = nullptr) :
_target(target)
{
id = idIdx++;
qDebug() << "SignalHolder construct " << id;
}
SignalHolder(const SignalHolder&) = delete;
SignalHolder(const SignalHolder&& c) :
_target(std::move(c._target))
{
qDebug() << "SignalHolder move construct " << id;
}
~SignalHolder()
{
qDebug() << "SignalHolder destruct " << id;
detach();
}
SignalHolder& operator=(SignalHolder const&) = delete;
SignalHolder& operator=(SignalHolder const&& c)
{
qDebug() << "SignalHolder assign move " << id;
_target = std::move(c._target);
//Break point here
int j = 9;
}
void detach() {
qDebug() << "SignalHolder detach " << id;
if (_target)
_target->detach();
_target = nullptr;
}
};
SignalHolder makeHolder()
{
auto s = std::make_shared<SignalCallbackBase>();
return SignalHolder(s);
}
int main()
{
SignalHolder a;
a = makeHolder();
}
参数c
声明为const
,不能移动。移动操作应该是对要移动的对象执行修改。在_target = std::move(c._target);
中,调用std::shared_ptr
的拷贝赋值操作符,而不调用移动赋值操作符。(std::shared_ptr
的move赋值操作符接受对非const对象的右值引用,不能绑定到const
对象)
您也应该删除const
限定符。
SignalHolder& operator=(SignalHolder && c)
{
qDebug() << "SignalHolder assign move " << id;
_target = std::move(c._target);
//Break point here
int j = 9;
return *this;
}
BTW:你在operator=
中丢失了返回语句。