我在使用句柄的库周围写一个小包装器。
该库的基本用途是:
int handle;
createHandle( 1, &handle )
doSomethingWithHandle( handle );
// ...
destroyHandle( handle );
我按照RAII原则制作了一个包装类:
Handle::Handle()
{
createHandle( 1, &m_handle );
}
Handle::~Handle()
{
if( m_handle!= 0 )
destroyHandle( m_handle );
}
Handle::Handle( Handle&& h ) :
m_handle( h.m_handle )
{
h.m_handle = 0;
}
Handle& Handle::operator=( Handle&& h )
{
m_handle = h.m_handle;
h.m_handle = 0;
return *this;
}
// copy constructor and copy assignment operator are explicitely deleted
它正在工作,但是,很多类依赖于那些包装器,这意味着每次类都有一个Handle成员时,我必须明确地编写移动构造函数/移动赋值运算符:
SomeClass::SomeClass( SomeClass&& s ) :
m_handle( std::move( s.m_handle ) )
{
}
SomeClass& SomeClass::SomeClass( SomeClass&& s )
{
m_handle = std::move( s.m_handle );
return *this;
}
这当然不难做到,但我想知道是否有办法避免这种情况,因为那是很多冗余的代码。
如果不可能,为什么移动操作符不是由编译器生成的?我们采取以下几点:
SomeClass a;
m_vector.push_back( a );
在这种情况下,someclass不可复制,因此编译器会出错,因为a.m_handle删除了复制操作符。所以这意味着我们必须移动它们。但是,如果我们这样做,那么我们是否希望移动每个成员(如果我们无法复制它们)?
编辑:我刚试了一下它似乎工作,只是使用默认声明移动运算符。这是我想的方式。但是"为什么"问题仍然存在。
Edit2:另一个例子
class Test
{
public:
Test()
{
m_vec.resize( 10 );
}
Test( const Test& ) = delete;
Test& operator=( const Test& ) = delete;
//Test( Test&& ) = default;
//Test& operator=( Test&& ) = default;
void cout()
{
std::cout << m_vec.size() << std::endl;
}
private:
std::vector< int > m_vec;
};
int main()
{
Test a;
std::vector< Test > v;
v.push_back( std::move( a ) );
v[ 0 ].cout();
}
答案 0 :(得分:0)
我必须明确地编写移动构造函数/移动赋值运算符:
这是你错的地方。要么根本不写它们并让编译器,或JButton button = new JButton("Hello");
this.getParent().add(button, BorderLayout.SOUTH);
它们。
=default;
你做错了,一定是:
SomeClass a;
m_vector.push_back( a );