简体   繁体   中英

c++ move operators class members

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();
}

I have to explicitely write move constructor/move assignment operators:

This is where you are wrong. Either do not write them at all and let the compiler, or =default; them.

SomeClass a;
m_vector.push_back( a );

You did that wrong, it must be:

SomeClass a;
m_vector.push_back( std::move(a) );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM