我有一些带有复制和移动分配的类,但是在我的示例中看起来移动操作是错误的,并导致了意外行为。为什么会调用移动函数并且我该如何避免这种情况?C1被赋值给C2后仍然需要使用,但是移动函数被调用并且C1变为空。
#include <iostream>
class CSomeClass
{
protected:
size_t m_uiSize = 0u;
public:
CSomeClass() {}
~CSomeClass() {}
size_t size() const { return m_uiSize; }
void resize( size_t p_uiNewSize ) { m_uiSize = p_uiNewSize; }
/* This operator I was expected to be called in all cases. */
CSomeClass& operator=( const CSomeClass& p_rzOther )
{
std::wcout << "Copy explicit" << std::endl;
m_uiSize = p_rzOther.size();
return *this;
}
CSomeClass& operator=( CSomeClass&& p_rzOther )
{
std::wcout << "Move explicit" << std::endl;
m_uiSize = p_rzOther.size();
p_rzOther.resize( 0u );
return *this;
}
#if 1
template<typename M> CSomeClass& operator=( const M& p_rzOther )
{
std::wcout << "Copy UNDEF" << std::endl;
m_uiSize = p_rzOther.size();
return *this;
}
template<typename M> CSomeClass& operator=( M&& p_rzOther )
{
std::wcout << "Move UNDEF" << std::endl;
p_rzOther.resize( 0u );
return *this;
}
#endif
};
int main()
{
CSomeClass C1;
CSomeClass C2;
C1.resize( 1u );
std::wcout << L"C1 size before: " << C2.size() << std::endl;
C2 = C1;
std::wcout << L"C1 size after: " << C2.size() << std::endl;
return 0;
}
这会导致以下输出结果:
C1 size before: 1
Move UNDEF
C1 size after: 0
我的实际问题比较复杂(有更多的模板和大量的变量分配方式)。
如果把#if 1
改成 #if 0
,正确的复制赋值运算符将被调用。但在我的实际代码中,有些情况下没有调用任何分配运算符(而是进行了错误的简单复制)。
希望您可以向我解释这种机制。我错过了什么吗?