c ++移动运算符类成员

时间:2016-06-26 16:21:29

标签: c++ c++11 move

我在使用句柄的库周围写一个小包装器。

该库的基本用途是:

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

1 个答案:

答案 0 :(得分:0)

  

我必须明确地编写移动构造函数/移动赋值运算符:

这是你错的地方。要么根本不写它们并让编译器,或JButton button = new JButton("Hello"); this.getParent().add(button, BorderLayout.SOUTH); 它们。

=default;

你做错了,一定是:

SomeClass a;
m_vector.push_back( a );