プレーンな 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 () { ...}
};
等
これは C++11 で改善できます: を使用できますunique_ptr<base>
(ただし、共変の戻り値の型は失われますbase_impl
) friend T
。
この場合、これはあまり柔軟ではないことに同意しますが、
- 多くの階層化された階層はあまり一般的ではありません
- クローン機能はあまり役に立ちません
- それにもかかわらず、設計は拡張可能であり、複製を超えています。定型コードを自動化する方法としてテンプレートを使用することは、たとえば. ATL と WTL。「不思議に繰り返されるテンプレート パターン」で検索してください。
別の解決策。これはおそらくさまざまな方法で改善される可能性がありますが、次の 2 つのクローン関数を使用することは避けられないと思います。
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)); }
};