我们有一个Base类和一个Derived派生自的类Base.
在其他一些类中,我们希望拥有一个类型的成员shared_ptr<Base>.
我们不能Base直接使用该类型,因为像这样的直接复制将排除子类.
但是,我们仍然希望Base在构造时"复制" (或子类)对象,因为我们想要排除它被修改的可能性.
处理此问题的经典方法是将虚拟成员函数clone()放入Base类中,Base然后可以实现每个子类.clone()然后每个人都会返回自己的"副本" - 例如,Derived会返回make_shared<Derived>(*this).
这种方法的问题是,这需要每个新的子类Base来实现这个clone()功能.每个代码clone()都是样板文件,一直重复它似乎有点不自然.
自C++ 11以来有没有更好的方法呢?
在普通的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.
我同意在这种情况下这不是很灵活,但是:
另一种方法.这可能会以各种方式改进,但我认为你不能避免有两个克隆功能:
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)