2016-08-11 15 views
1

私はC++の初心者ですので、助けてください。 テンプレートクラスをコンストラクタのパラメータとして使用することはできません。 xcodeに 'が表示されます。' Work 'の初期化に一致するコンストラクタがありません'エラー。 以下のソースコード全体が、これを修正できますか?C++のテンプレート<基本クラスと派生クラス>

#include <iostream> 
class Base { 
public: 
    virtual void hello_world() const { 
     printf("Base::hello_world()\n"); 
    }; 
}; 

class Derived : public Base { 
public: 
    void hello_world() const { 
     printf("Derived::hello_world()\n"); 
    }; 
}; 

template<class T> 
class Templ { 
public: 
    Templ(const T &t) : _value(t) {} 

    const T& getValue() const{ 
     return _value; 
    } 
private: 
    const T &_value; 
}; 

class Work { 
public: 
    Work(const Templ<Base*> &base) : mBase(base) {} 

    void working() { 
     mBase.getValue()->hello_world(); 
    } 
private: 
    const Templ<Base*> &mBase; 
}; 

int main(int argc, const char * argv[]) { 
    Templ<Base*> base(new Base()); 
    //OK 
    Work w_base(base); 

    Templ<Derived*> derived(new Derived()); 
    //error: No matching constructor for initialization of 'Work' 
    Work w_derived(derived); 

    return 0; 
} 
+0

これらの参考資料は怖いです。 'Base *'ポインタ 'base._value'の生涯は何を指していますか? – aschepler

答えて

1

Work w_derived(derived);WorkTempl<Base*>を期待して仕事に行くことはありません。 Templ<Base*>Templ<Derived*>は、2つの異なるタイプです。ちょうどaのようなstd::vector<int>std::vector<std::complex>と同じではありません。

あなたができることは、DerviedへのポインタからTempl<Base*>を作成し、それにWorkを作成することです。あなたがポリモーフィズムを使用しているので、コメントで指摘したようにLive Example

Templ<Base*> derived(new Derived()); 
Work w_derived(derived); 

のようなものはまた、あなたは、基本クラスで仮想デストラクタを持っている必要があります。デストラクタが仮想でない場合、基本クラスのデストラクタだけが実行され、オブジェクトは適切に破棄されません。

C++で
+0

また、topicstarterは、いくつかの出力をデストラクタに追加し、仮想/非仮想デストラクタを使用して遊ぶのに役立ちます。 –

+0

@VictorIstomin良い点。彼らは仮想デストラクタがないことに気付かなかった。 – NathanOliver

0

、これはこの

struct Base 
{ 
    virtual ~Base() {} // enable descruction of base through pointer to Base 
    virtual void hello_world() const 
    { std::cout<<"Base::hello_world()\n"; } 
}; 

struct Derived : Base 
{ 
    void hello_world() const override 
    { std::cout<<"Derived::hello_world()\n"; } 
}; 

struct work 
{ 
    work(const Base*p) 
    : ptr(p) {} 
    void working() const 
    { ptr->hello_world(); } 
private: 
    std::unique_ptr<const Base> ptr; 
}; 

int main() 
{ 
    Work w_base(new Base); 
    Work w_derived(new Derived); 
    w_base.working(); 
    w_derived.working(); 
} 

注ようになり、次の

  1. Basevirtualデストラクタは、派生クラスが適切std::unique_ptr<>のように、Baseへのポインタから破壊されることを保証します正しく動作します。
  2. overrideキーワードは、実際に仮想メソッドを実装することを保証します。
  3. std::unique_ptr<>の使用により、Templクラスが回避されます。 Morever、そのデストラクタは自動的に、そしてあなたのコードのメモリリークを避けるためにpointed-toオブジェクトを正しく破棄します。
  4. return 0は、int main()では必須ではありませんが、自動的に生成されます。
関連する問題