繁体   English   中英

C ++ 11-指向抽象类型的智能指针的副本构造?

[英]C++11 - Copy construction of a smart pointer pointing to abstract type?

我喜欢std :: unique_ptr 它可以帮助我防止内存泄漏,这非常有用。 但是有一个问题:不允许拷贝分配和构造。

即使此限制为程序员的安全提供了保障,但它也是相当有限的。 如果使用副本分配和构造将std :: unique_ptr作为其成员的类,则最终会遇到问题。 这就是为什么我用复制结构和赋值围绕unique_ptr创建自己的包装器的原因。 这是复制构造函数:

template<typename T, class Deleter>
PointerSmartSafe<T, Deleter>::PointerSmartSafe(PointerSmartSafe const& pointer_smart_safe_) noexcept : _m_opPointerUnique((_m_opPointerUnique == nullptr) ? new T(*_m_opPointerUnique.get()) : nullptr){

}

这是副本分配运算符:

template<typename T, class Deleter>
PointerSmartSafe<T, Deleter>& PointerSmartSafe<T, Deleter>::operator=(PointerSmartSafe const& pointer_smart_safe_) noexcept{
    _m_opPointerUnique = decltype(_m_opPointerUnique)(new T(*_m_opPointerUnique.get()));
    return *this;
}

一切工作正常,直到我最终将抽象基类用作类型(T)。 我收到如下错误消息:

error: cannot allocate an object of abstract type 'AbstractBaseClass'

这使我感到困惑。 是否有解决方法?

但是有一个问题:不允许拷贝分配和构造。

那不是问题。 如果发现问题,则说明您做错了什么。

即使此限制为程序员的安全提供了保障,但它也是相当有限的。

它是有意限制的,也许您应该重新考虑您的设计。

这就是为什么我用复制结构和赋值围绕unique_ptr创建自己的包装器的原因。

那么您想要的不是unique_ptr ,而是“克隆ptr”

这使我感到困惑

到底有什么困惑? 您正在尝试创建抽象基类的实例。 您的代码还将切片非抽象基数。 本质上是不安全的。

这应该告诉您一些重要的信息:无法一般地复制unique_ptr持有的对象,它需要unique_ptr没有的上下文。 该上下文要么来自拥有您要复制的对象的对象(要求拥有对象知道对象的动态类型),要么来自您想要复制的对象(可以使用虚函数在其中复制)正确的动态类型的上下文。)

传统的解决方案是将虚拟clone()成员函数添加到您的类型中,然后在可能时使用它。

您可以将其合并到构造函数中,如下所示:

template<typename T>
  auto clone(T* t) -> decltype(t->clone())
  { return t->clone(); }

template<typename T>
  std::unique_ptr<T> clone(T* t, ...)
  { return std::unique_ptr<T>(new T(*t)); }

// ... 

_m_opPointerUnique((_m_opPointerUnique == nullptr) ? clone(_m_opPointerUnique.get()) : nullptr)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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