c++ - move 类的构造函数

标签 c++ c++11 move-semantics move-constructor movable

我写了两个类,但我在将它们放入 vector 中时遇到了问题:

#include <vector>
#include <iostream>
#include <fstream>

class A
{
public:
    std::ofstream filestream;
    int aa1;
    int aa2;
    int aa3;
    int aa4;
    int aa5;
    int aa6;
    int aa7;
    int aa8;
    int aa9;
    int aa10;

    A() {}
    ~A() {}
};

class B
{
    A aaa;
public:
    int b1;
    int b2;
    int b3;
    int b4;
    int b5;
    int b6;
    int b7;
    int b8;
    int b9;
    int b10;

    B() {}
    ~B() {}
};

int main()
{
    std::vector<B> vec;
    vec.emplace_back();
    return 0;
}

输出信息:

g++ -std=c++11 main.cpp



In file included from /usr/include/c++/5/vector:62:0,
                 from main.cpp:1:
/usr/include/c++/5/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = B; _Args = {B}]’:
/usr/include/c++/5/bits/stl_uninitialized.h:75:18:   required from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<B*>; _ForwardIterator = B*; bool _TrivialValueTypes = false]’
/usr/include/c++/5/bits/stl_uninitialized.h:126:15:   required from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<B*>; _ForwardIterator = B*]’
/usr/include/c++/5/bits/stl_uninitialized.h:281:37:   required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator<B*>; _ForwardIterator = B*; _Tp = B]’
/usr/include/c++/5/bits/stl_uninitialized.h:303:2:   required from ‘_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = B*; _ForwardIterator = B*; _Allocator = std::allocator<B>]’
/usr/include/c++/5/bits/vector.tcc:422:8:   required from ‘void std::vector<_Tp, _Alloc>::_M_emplace_back_aux(_Args&& ...) [with _Args = {}; _Tp = B; _Alloc = std::allocator<B>]’
/usr/include/c++/5/bits/vector.tcc:101:23:   required from ‘void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {}; _Tp = B; _Alloc = std::allocator<B>]’
main.cpp:46:22:   required from here
/usr/include/c++/5/bits/stl_construct.h:75:7: error: use of deleted function ‘B::B(const B&)’
     { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
       ^
main.cpp:24:7: note: ‘B::B(const B&)’ is implicitly deleted because the default definition would be ill-formed:
 class B
       ^
main.cpp:24:7: error: use of deleted function ‘A::A(const A&)’
main.cpp:5:7: note: ‘A::A(const A&)’ is implicitly deleted because the default definition would be ill-formed:
 class A
       ^
main.cpp:5:7: error: use of deleted function ‘std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const std::basic_ofstream<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]’
In file included from main.cpp:3:0:
/usr/include/c++/5/fstream:723:7: note: declared here
       basic_ofstream(const basic_ofstream&) = delete;
       ^

警告和错误是不言自明的。但是我是新来的一些类(class)。我应该如何正确 move ofstream ?如果我定义一个 move constructor ,我也应该将所有单个元素从 aa1 move 到 aa10 吗?有什么办法绕过它吗?

根据其他posts , 对于我的 g++ 版本,ofstream 必须是可 move 的。为什么它不隐式 move ?

g++ -v
 ...
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.5) 

最佳答案

Why doesn't it move implicitly?

move 构造函数不会是implicitly declared当提供用户定义的析构函数时:

  • there are no user-declared copy constructors;
  • there are no user-declared copy assignment operators;
  • there are no user-declared move assignment operators;
  • there are no user-declared destructors;

您可以删除AB 的析构函数声明,让编译器为您生成 move 构造函数,或者您可以使用 显式定义它们默认。对于这两种情况, move 构造函数都对对象的基类和非静态成员执行完整的成员智能 move 。例如

class A
{
public:
    ...
    A(A&&) = default;
};

class B
{
public:
    ...
    B(B&&) = default;
};

LIVE

关于c++ - move 类的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47425050/

相关文章:

无法命名的 C++ 类型

c++ - 将 shared_ptr 用于 private_key 时出现段错误

c++ - 使用枚举类定义标志

c++ - 如何从工厂方法返回 unique_ptr?

c++ - 为什么我得到 Present table dump for device[1] : NVIDIA Tesla GPU 0 in this code?

c++ - 我想以相反的顺序闪烁 LED

c++ - 是否应该使用 unique_ptr 来更轻松地实现 "move"语义?

c++ - C++ 标准中与 [basic.link]/7 相关的 GCC 和 clang 之间的矛盾结果

c++ - std::move 和 std::copy 是否相同?

c++ - static_cast 为不同的类型,并 move 结果