Scott Myers が書いたように、C++ の型システムの緩和を利用して clone() を宣言し、宣言されている実際の型へのポインターを返すことができます。
class Base
{
virtual Base* clone() const = 0;
};
class Derived : public Base
{
virtual Derived* clone() const
};
コンパイラは、clone() がオブジェクトの型へのポインターを返すことを検出し、Derived がそれをオーバーライドして、派生へのポインターを返すことを許可します。
次のように、所有権のセマンティクスの転送を意味するスマート ポインターを clone() が返すようにすることが望ましいでしょう。
class Base
{
virtual std::auto_ptr<Base> clone() const = 0;
};
class Derived : public Base
{
virtual std::auto_ptr<Derived> clone() const;
};
残念ながら、規則の緩和はテンプレート化されたスマート ポインターには適用されず、コンパイラーはオーバーライドを許可しません。
したがって、次の 2 つのオプションが残っているようです。
- clone() に「ダム」ポインターを返させ、クライアントがそれを破棄する責任があることを文書化します。
- clone() がスマート ベース ポインターを返すようにし、必要に応じてクライアントが dynamic_cast を使用して派生ポインターに保存するようにします。
これらのアプローチのいずれかが優先されますか? または、所有権のセマンティクスの譲渡を食べて、強力な型の安全性も確保する方法はありますか?