I am writting a small wrapper around a library that uses handles.
Basic uses of this library are :
int handle;
createHandle( 1, &handle )
doSomethingWithHandle( handle );
// ...
destroyHandle( handle );
I made a wrapper class following RAII principles:
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
It's working, however, a lot a classes depends on those wrappers, which means everytime a class has a Handle member, I have to explicitely write move constructor/move assignment operators:
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;
}
This is, of course, not hard to do, but I wonder if there is a way to avoid that, because thats a lot of redundant code.
If that's not possible, why aren't the move operators not generated by the compiler? Let's take the following lines:
SomeClass a;
m_vector.push_back( a );
In this case, someclass is not copyable so the compiler will have an error because a.m_handle have copy operators deleted. So it means we HAVE to move them. But if we do, doesn't it makes sence that we want to move every members ( if we can't copy them )?
Edit: I just tried something and it seems to work, just declare the move operators using default. This is the way to go I suppose. But the "why" question remains.
Edit2: Another example
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();
}
Aucun commentaire:
Enregistrer un commentaire