2017-08-21 9 views
1

テンプレートを作成するには? まず、私はベースとしてブックを持っている:スタティックファクトリメソッドのテンプレートを作成するには?

class Book { 
public: 
    Book() {} 
    ~Book() {} 
} 

その後ComputerBook:

class ComputerBook: public Book { 
public: 
    static ComputerBook* create() { 
     return new ComputerBook(); 
    } 
private: 
    ComputerBook():Book() {} 
} 

次に電話帳:だから

class PhoneBook1: public PhoneBook { 
public: 
    static PhoneBook1* create() { 
     return new PhoneBook1(); 
    } 
private: 
    PhoneBook1():PhoneBook() {} 
} 


class PhoneBook2: public PhoneBook { 
public: 
    static PhoneBook2* create() { 
     return new PhoneBook2(); 
    } 
private: 
    PhoneBook2():PhoneBook() {} 
} 

class PhoneBook: public Book { 
public: 
    static PhoneBook* create() { 
     return new PhoneBook(); 
    } 
private: 
    PhoneBook():Book() {} 
} 

電話帳は、二つの遺産を持っていますマージできるComputerBookとPhoneBook1、PhoneBook2をテンプレートで1つにする?

+1

'return new WhateverBook()'普通のコンストラクタを使用してみませんか?また、このタイプの問題のテンプレートは必要ありません。継承と仮想関数で十分です。 –

+0

多分あなたは正しいです。私はそれにテンプレートを適用することが可能である場合だけ考えています。 – user8073659

+1

私はそれをテンプレートに変換するのが不愉快です。これは、多くの点で矛盾し、間違っているため、このコードで何をしたいのかは不明です。テンプレートを適用すると状況が悪化します。 –

答えて

2

あなたがしようとしているところから、すべての書籍についてcreateという静的ファクトリメソッドを作成しています。あなたはこのように、このメソッドをテンプレート化することができます

class Book { 
public: 
    Book() {} 
    ~Book() {} 
    template<typename T> 
    static Book* create() { 
     return new T(); 
    } 
} 

そして、電話帳を作るために:

Book::create<PhoneBook1>(); 

はまた、各書籍のためのコンストラクタは、公開されていることを確認し、またはBook::create静的メソッドの友人。

+0

私はこの答えに何が間違っているのか分かりません。誰か説明してもらえますか? – RazeLighter777

+0

この愚かなファクトリ関数は、最初に存在すべきではありません。あなたは、不必要に多型を上に加えるだけでそれを悪化させます。 –

1

希望するものは(おそらく)CRTPです。メソッドcreateを基本クラスに定義します。ここでは、テンプレートパラメータである派生クラスでパラメータ化されています。テンプレートベースを継承する場合、派生クラスをプラグインし、正しいタイプの関数createを魔法のように取得します。

なぜ個人用のコンストラクタがあるのか​​、なぜこのファクトリ関数が必要なのか分かりません。

template < typename Derived > 
class Book { 
    friend Derived; 
public: 
    Book() {} 
    ~Book() {} 
    static Derived* create() { 
    return new Derived{}; 
    } 
}; 

class ComputerBook: public Book<ComputerBook> { 
    // Make the base class a friend so we can access the private constructor 
    friend class Book<ComputerBook>; 
private: 
    ComputerBook() : Book() {} 
}; 

template < typename Derived > 
class PhoneBook: public Book<Derived> {}; // no private constructor, no 'friend' needed 

class PhoneBook1: public PhoneBook<PhoneBook1> {}; 
class PhoneBook2: public PhoneBook<PhoneBook2> {}; 

int main() 
{ 
    auto cb = ComputerBook::create(); 
    auto pb1 = PhoneBook1::create(); 
    auto pb2 = PhoneBook2::create(); 
    delete cb; 
    delete pb1; 
    delete pb2; 
} 
関連する問題