13

下に労働者Cloneable/CloneableImpl階級のペアがあります。子から親へのデフォルトのコンストラクターがある限り、それはその仕事をします。

Animal のコンストラクターが に変更されたAnimal( std::string const& name )とします。これには、子クラスのコンストラクターから名前を渡す必要があります。

Cloneable/CloneableImplジェネリックを維持しながら、この要件を構造に組み込むにはどうすればよいですか?

つまり、Lion、Tiger から Animal までのすべてのコンストラクター引数を転送できる必要があります。一般的な方法で C++11 でこれを行う方法はありますか?

それが不可能な場合、これらのテンプレートを再構築して、コンストラクターの要件を考慮しながら汎用性を維持するにはどうすればよいでしょうか?

コード

template<typename P>
struct Cloneable
{
    virtual P* clone() const = 0;
};

template<typename T,typename P>
struct CloneableImpl :
    public P
{
    virtual P* clone() const 
    {
        return new T( dynamic_cast<T const&>(*this));
    }
};

// ----------------------------------------------------------------------------

struct Animal :
    public Cloneable<Animal>
{ 
};

struct Lion  : 
    public CloneableImpl<Lion,Animal> 
{ 
};

struct Tiger : 
    public CloneableImpl<Tiger,Animal> 
{ 
};

int
main( int argv, char* argc[] )
{
    Animal* x = new Lion;
    Animal* y = x->clone();

    // we want to do this without hard-coding in template classes
    // Animal* z = new Lion( "Samba" );  
}
4

1 に答える 1

12

@Cheersandhth.-Alf と @R. OP へのコメントでの Martinho Fernandes の提案は、完全な転送を検討します。私は少し研究し、これを思いつきました。これはうまくいくようです。

みんなありがとう!

コード

#include <string>
#include <iostream>

template<typename P>
struct Cloneable
{
    virtual P* clone() const = 0;
};

template<typename T,typename P>
struct CloneableImpl :
    public P
{
    template<typename... Args>
    CloneableImpl( Args&&... args ) 
       : P(std::forward<Args>(args)...)
  {  }

    virtual P* clone() const 
    {
        return new T( dynamic_cast<T const&>(*this));
    }
};

// ----------------------------------------------------------------------------

struct Animal :
    public Cloneable<Animal>
{ 
    Animal( std::string const& name ) : m_name( name ) { }

    std::string  m_name;
};

struct Lion  : 
    public CloneableImpl<Lion,Animal> 
{ 
    template<typename... Args>
    Lion( Args&&... args ) 
       : CloneableImpl<Lion,Animal>(std::forward<Args>(args)...)
  {  }
};

struct Tiger : 
    public CloneableImpl<Tiger,Animal> 
{ 
};

int
main( int argv, char* argc[] )
{
    Animal* x = new Lion( "Samba" );
    Animal* y = x->clone();

    std::cerr << y->m_name << std::endl;
} 
于 2013-01-02T13:27:59.530 に答える