gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 00:36:38 25 4
gpt4 key购买 nike

我喜欢 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'

这让我很困惑。是否有解决方法?

最佳答案

But there's one problem: copy assignment and construction is not allowed.

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

Even though this restriction serves safety of a programmer, it is quite limiting, too.

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

That's why I created my own wrapper around unique_ptr with copy construction and assignment.

你想要的不是 unique_ptr 那么,你想要一个“克隆 ptr”

This perplexes me

它有什么令人困惑的地方?您正在尝试创建抽象基类的实例。您的代码还将对非抽象基础进行切片。它本质上是不安全的。

这应该告诉您一些重要的事情:复制 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)

关于C++11 - 复制指向抽象类型的智能指针的构造?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15659349/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com