C++ 11中存储的任何好的新方法,作为成员,"克隆"其他"层次结构类"的对象?

Den*_*hie 4 c++

我们有一个Base类和一个Derived派生自的类Base.

在其他一些类中,我们希望拥有一个类型的成员shared_ptr<Base>.

我们不能Base直接使用该类型,因为像这样的直接复制将排除子类.

但是,我们仍然希望Base在构造时"复制" (或子类)对象,因为我们想要排除它被修改的可能性.

处理此问题的经典方法是将虚拟成员函数clone()放入Base类中,Base然后可以实现每个子类.clone()然后每个人都会返回自己的"副本" - 例如,Derived会返回make_shared<Derived>(*this).

这种方法的问题是,这需要每个新的子类Base来实现这个clone()功能.每个代码clone()都是样板文件,一直重复它似乎有点不自然.

自C++ 11以来有没有更好的方法呢?

Ale*_* C. 5

在普通的C++中始终可以这样做:

struct base
{
    virtual ~base () {}
    virtual base* clone () = 0;  
    virtual void foo () = 0;
};

template <typename T>
struct base_impl : base
{
    T* clone () { return new T (*static_cast<T*> (this)); }
};

struct derived : base_impl<derived>
{ 
    void foo () { ... }
};

struct derived2 : base_impl<derived2>
{
    void foo () { ...}
};
Run Code Online (Sandbox Code Playgroud)

等等

您可以使用C++ 11改进这一点:您可以使用unique_ptr<base>(但是您丢失了协变返回类型),您可以将析构函数设为base_impl私有并使用friend T.

我同意在这种情况下这不是很灵活,但是:

  • 许多分层的层次结构并不常见
  • 克隆函数不是很有用
  • 然而,设计是可扩展的并且超越了克隆:使用模板作为自动化样板代码的方法在例如中被彻底使用.ATL和WTL.搜索"奇怪的重复模板模式".

另一种方法.这可能会以各种方式改进,但我认为你不能避免有两个克隆功能:

struct base
{
    std::unique_ptr<base> clone () { return std::unique_ptr<base> (do_clone ()); }

private:
    virtual base *do_clone () = 0;
};

template <typename T>
struct base_impl : base
{
    std::unique_ptr<T> clone () 
    {
        return std::unique_ptr<T> (static_cast<T*> (do_clone ()));
    }    

private:
    base *do_clone () { return new T (*static_cast<T*> (this)); }
};
Run Code Online (Sandbox Code Playgroud)