unique_ptr是否需要复制构造函数?

时间:2019-10-28 21:20:48

标签: c++ c++14 unique-ptr

我试图在一个小项目中摆脱原始指针。唯一仍需要指针的地方是指向多态类的指针数组,我正在尝试用unique_ptr替换它们:

class BaseClass {
  public:
    BaseClass() = default;
    virtual void function() = 0;
    virtual ~BaseClass() = default;

    // C.67: A polymorphic class should suppress copying.
    BaseClass(const BaseClass&) = delete;
    BaseClass& operator=(const BaseClass&) = delete;
};

class DerivedClass : public BaseClass {
  public:
    DerivedClass() {}
    void function() override {}
    ~DerivedClass() = default;
};

vector<unique_ptr<BaseClass>> values{
  make_unique<DerivedClass>(),
  make_unique<DerivedClass>()
};

但是,此代码触发以下错误:

In file included from bug.cpp:5:
In file included from /usr/include/c++/v1/vector:266:
In file included from /usr/include/c++/v1/__bit_reference:15:
In file included from /usr/include/c++/v1/algorithm:643:
/usr/include/c++/v1/memory:1805:31: error: call to implicitly-deleted copy constructor of
      'std::__1::unique_ptr<BaseClass, std::__1::default_delete<BaseClass> >'
            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
                              ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/v1/memory:1715:18: note: in instantiation of function template specialization
      'std::__1::allocator<std::__1::unique_ptr<BaseClass, std::__1::default_delete<BaseClass> > >::construct<std::__1::unique_ptr<BaseClass, std::__1::default_delete<BaseClass> >, const
      std::__1::unique_ptr<BaseClass, std::__1::default_delete<BaseClass> > &>' requested here
            {__a.construct(__p, _VSTD::forward<_Args>(__args)...);}
                 ^
/usr/include/c++/v1/memory:1561:14: note: in instantiation of function template specialization
      'std::__1::allocator_traits<std::__1::allocator<std::__1::unique_ptr<BaseClass, std::__1::default_delete<BaseClass> > > >::__construct<std::__1::unique_ptr<BaseClass,
      std::__1::default_delete<BaseClass> >, const std::__1::unique_ptr<BaseClass, std::__1::default_delete<BaseClass> > &>' requested here
            {__construct(__has_construct<allocator_type, _Tp*, _Args...>(),
             ^
/usr/include/c++/v1/memory:1645:17: note: in instantiation of function template specialization
      'std::__1::allocator_traits<std::__1::allocator<std::__1::unique_ptr<BaseClass, std::__1::default_delete<BaseClass> > > >::construct<std::__1::unique_ptr<BaseClass,
      std::__1::default_delete<BaseClass> >, const std::__1::unique_ptr<BaseClass, std::__1::default_delete<BaseClass> > &>' requested here
                construct(__a, _VSTD::__to_raw_pointer(__begin2), *__begin1);
                ^
/usr/include/c++/v1/vector:1030:21: note: in instantiation of function template specialization
      'std::__1::allocator_traits<std::__1::allocator<std::__1::unique_ptr<BaseClass, std::__1::default_delete<BaseClass> > > >::__construct_range_forward<const std::__1::unique_ptr<BaseClass,
      std::__1::default_delete<BaseClass> > *, std::__1::unique_ptr<BaseClass, std::__1::default_delete<BaseClass> > *>' requested here
    __alloc_traits::__construct_range_forward(__a, __first, __last, this->__end_);
                    ^
/usr/include/c++/v1/vector:1289:9: note: in instantiation of function template specialization
      'std::__1::vector<std::__1::unique_ptr<BaseClass, std::__1::default_delete<BaseClass> >, std::__1::allocator<std::__1::unique_ptr<BaseClass, std::__1::default_delete<BaseClass> > >
      >::__construct_at_end<const std::__1::unique_ptr<BaseClass, std::__1::default_delete<BaseClass> > *>' requested here
        __construct_at_end(__il.begin(), __il.end(), __il.size());
        ^
bug.cpp:28:31: note: in instantiation of member function 'std::__1::vector<std::__1::unique_ptr<BaseClass, std::__1::default_delete<BaseClass> >, std::__1::allocator<std::__1::unique_ptr<BaseClass,
      std::__1::default_delete<BaseClass> > > >::vector' requested here
vector<unique_ptr<BaseClass>> values{
                              ^
/usr/include/c++/v1/memory:2440:3: note: copy constructor is implicitly deleted because
      'unique_ptr<BaseClass, std::__1::default_delete<BaseClass> >' has a user-declared move constructor
  unique_ptr(unique_ptr&& __u) noexcept
  ^
1 error generated.

使用unique_ptr似乎需要一个复制构造函数,这没有意义:

  • 如果它是unique_ptr的副本,这有点讽刺,因为unique_ptr的主要目的是防止复制
  • 如果它是具体类型的副本,这也有点讽刺意味,因为在现代C ++中,unique_ptr的唯一合法用法应该是指向多态类的指针,这应该抑制副本构造函数。

我在做什么错了?

0 个答案:

没有答案