Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在某些智能指针中实现深度复制功能?_C++_Smart Pointers - Fatal编程技术网

C++ 如何在某些智能指针中实现深度复制功能?

C++ 如何在某些智能指针中实现深度复制功能?,c++,smart-pointers,C++,Smart Pointers,unique_ptr非常有用。但是,它是不可复制的。如果为其定点类提供virutal clone deep copy方法,我认为它会变得更有用。是否有必要或有更好的方法来实施它?某些库中是否存在类似的智能指针?这是一个版本 template<class T> class deep_ptr: private unique_ptr<T> { public: using unique_ptr<T>::operator *; using unique_

unique_ptr非常有用。但是,它是不可复制的。如果为其定点类提供virutal clone deep copy方法,我认为它会变得更有用。是否有必要或有更好的方法来实施它?某些库中是否存在类似的智能指针?这是一个版本

template<class T>
class deep_ptr: private unique_ptr<T>
{
public:
    using unique_ptr<T>::operator *;
    using unique_ptr<T>::operator ->;
    using unique_ptr<T>::operator bool;
    using unique_ptr<T>::release;
    using unique_ptr<T>::reset;
    using unique_ptr<T>::get;

    // add (DEFAULT_CONSTRUCTOR)(MOVE_CONSTRUCTOR)(MOVE_ASSIGNMENT_METHOD) ...

    explicit deep_ptr(T* p) : unique_ptr(p) {}

    deep_ptr(deep_ptr const& r) : unique_ptr(r->clone()) {}

    deep_ptr& operator=(deep_ptrconst& r)
    { if (this != &r) reset(r->clone()); return *this; }
};

Juse觉得它很有用,但从未见过类似的东西

除非我误解了您要查找的内容,否则,如果类有克隆方法,那应该足以获得您要查找的内容

示例代码:

#include <iostream>
#include <memory>

struct A
{
   virtual ~A() {}
   virtual A* clone() = 0;
};

struct B : A
{
   B(int in = 0) : x(in) {}
   B(B const& copy) : x(copy.x) {}
   virtual ~B() {std::cout << "In B::~B()\n";}

   virtual A* clone() { return new B(*this); }
   int x;
};

int main()
{
   std::unique_ptr<A> p1(new B(10));
   std::unique_ptr<A> p2(p1->clone());
   return 0;
}
运行上述程序的输出:

In B::~B() In B::~B()
除非我误解了您在寻找什么,否则,如果一个类有一个clone方法,这应该足以得到您想要的

示例代码:

#include <iostream>
#include <memory>

struct A
{
   virtual ~A() {}
   virtual A* clone() = 0;
};

struct B : A
{
   B(int in = 0) : x(in) {}
   B(B const& copy) : x(copy.x) {}
   virtual ~B() {std::cout << "In B::~B()\n";}

   virtual A* clone() { return new B(*this); }
   int x;
};

int main()
{
   std::unique_ptr<A> p1(new B(10));
   std::unique_ptr<A> p2(p1->clone());
   return 0;
}
运行上述程序的输出:

In B::~B() In B::~B()
如果没有克隆方法,仅使用复制构造函数,则以下内容应能正常工作:

template <typename T>
class deep_ptr
{
public:
  deep_ptr() : i_() {}

  deep_ptr(std::nullptr_t) : i_(nullptr) {}

  template <typename U>
    deep_ptr(U* u) : i_(u ? new inner_impl<U>(*u) : nullptr) {}

  ~deep_ptr() { delete i_; }

  deep_ptr(const deep_ptr& p) : i_(p.i_ ? p.i_->copy() : nullptr) {}

  deep_ptr& operator=(const deep_ptr& p)
  {
    if (!p.i_) { i_ = nullptr; }
    else { i_ = p.i_->copy(); }
  }

  deep_ptr(deep_ptr&& p) : i_(p.i_) { p.i_ = nullptr; }

  deep_ptr& operator=(deep_ptr&& p)
  {
    i_ = p.i_;
    p.i_ = nullptr;
  }

  const T* operator->() const { return get(); }

  const T* get() const
  {
    if (i_) { return *i_; }
    return nullptr;
  }

  const T& operator*() const { return *static_cast<T*>(*i_); }

  T* operator->() { return get(); }

  T* get()
  {
    if (i_) { return *i_; }
    return nullptr;
  }

  T& operator*(){ return *static_cast<T*>(*i_); }

private:
  struct inner
  { 
    virtual inner* copy() const = 0;
    virtual operator const T*() const  = 0;
    virtual operator T*() = 0;
    virtual ~inner() {}
  };

  inner* i_;

  template <typename U>
  struct inner_impl : inner
  {
    inner_impl(const U& u) : u_(u) {}
    inner_impl* copy() const override { return new inner_impl(u_); }
    operator const T*() const override { return &u_; }
    operator T*() override { return &u_; }

    U u_;
  };
};

如果没有克隆方法,仅使用复制构造函数,则以下内容应能正常工作:

template <typename T>
class deep_ptr
{
public:
  deep_ptr() : i_() {}

  deep_ptr(std::nullptr_t) : i_(nullptr) {}

  template <typename U>
    deep_ptr(U* u) : i_(u ? new inner_impl<U>(*u) : nullptr) {}

  ~deep_ptr() { delete i_; }

  deep_ptr(const deep_ptr& p) : i_(p.i_ ? p.i_->copy() : nullptr) {}

  deep_ptr& operator=(const deep_ptr& p)
  {
    if (!p.i_) { i_ = nullptr; }
    else { i_ = p.i_->copy(); }
  }

  deep_ptr(deep_ptr&& p) : i_(p.i_) { p.i_ = nullptr; }

  deep_ptr& operator=(deep_ptr&& p)
  {
    i_ = p.i_;
    p.i_ = nullptr;
  }

  const T* operator->() const { return get(); }

  const T* get() const
  {
    if (i_) { return *i_; }
    return nullptr;
  }

  const T& operator*() const { return *static_cast<T*>(*i_); }

  T* operator->() { return get(); }

  T* get()
  {
    if (i_) { return *i_; }
    return nullptr;
  }

  T& operator*(){ return *static_cast<T*>(*i_); }

private:
  struct inner
  { 
    virtual inner* copy() const = 0;
    virtual operator const T*() const  = 0;
    virtual operator T*() = 0;
    virtual ~inner() {}
  };

  inner* i_;

  template <typename U>
  struct inner_impl : inner
  {
    inner_impl(const U& u) : u_(u) {}
    inner_impl* copy() const override { return new inner_impl(u_); }
    operator const T*() const override { return &u_; }
    operator T*() override { return &u_; }

    U u_;
  };
};

你能发布几行代码来说明你打算如何使用它吗?@GuyGreer哦,糟糕,我误解了这个问题。@GuyGreer-shared\u ptr既没有深层的复制语义,也没有浅层的复制语义。这取决于它指向的对象to@EdHeal我的意思是复制共享的ptr不会复制底层对象,这使得它是一个浅拷贝,除非我误解了什么。。。。但是,它是不可复制的-使其可复制会造成两个唯一的\u ptr管理同一对象的情况。这将打破unique_ptr的单一所有权语义。你能发布几行代码来说明你打算如何使用它吗?@GuyGreer哦,糟糕,我误解了这个问题。@GuyGreer-shared_ptr既没有深度复制语义,也没有浅层复制语义。这取决于它指向的对象to@EdHeal我的意思是复制共享的ptr不会复制底层对象,这使得它是一个浅拷贝,除非我误解了什么。。。。但是,它是不可复制的-使其可复制会造成两个唯一的\u ptr管理同一对象的情况。这将打破unique_ptr的单一所有权语义。如果指针是可深度复制的类的成员。我不能使用隐式复制构造函数。@user1899020,你的意思是如果std::unique\u ptr是一个类的成员…?,比如类a{unique\u ptr mB;…},并且要使一个复制构造函数可复制,我们需要编写一个复制构造函数。如果使用deep_ptr,我们可以使用编译器提供的版本。@user1899020,除非您有很多这样的类,否则最好为编写一个复制构造函数,而不是从std::unique_ptr派生。如果指针是可深度复制的类的成员。我不能使用隐式复制构造函数。@user1899020,你的意思是如果std::unique\u ptr是一个类的成员…?,比如类a{unique\u ptr mB;…},并且要使一个复制构造函数可复制,我们需要编写一个复制构造函数。如果使用deep_ptr,我们可以使用编译器提供的版本。@user1899020,除非您有很多这样的类,否则最好为a编写一个复制构造函数,而不是从std::unique_ptr派生。