2012-03-11 4 views
0

未分化テンプレートタイプができないので、私は、基本型への参照を有することができるようにするために使用される非テンプレート抽象基底クラスを有しますメソッドの引数として使用されます。 1はICallbackから継承したコンクリート型を作成することができ、最後にC++方法:抽象特殊テンプレートを継承非テンプレートクラス

#ifndef RPCPP_ICALLBACK_H 
#define RPCPP_ICALLBACK_H 

#include "ICallbackBase.h" 

namespace rpcpp 
{ 
template <class T> 
class ICallback : public ICallbackBase 
{ 
public: 
    virtual ~ICallback() {}; 
    virtual void OnSuccess(T result) = 0; 
    virtual void OnError(std::string error) = 0; 
}; 
} 

#endif // RPCPP_ICALLBACK_H 

#ifndef RPCPP_ICALLBACKBASE_H 
#define RPCPP_ICALLBACKBASE_H 

#include <string> 

namespace rpcpp 
{ 
    class ICallbackBase 
{ 
public: 
    virtual ~ICallbackBase() {}; 
    virtual void OnSuccess(void result) = 0; 
    virtual void OnError(std::string error) = 0; 
}; 
} 

#endif // RPCPP_ICALLBACKBASE_H 

抽象テンプレートクラスICallbackはICallbackベースから、そのように継承するすべての

#ifndef RPCPP_SAMPLE_CALLBACK_H 
#define RPCPP_SAMPLE_CALLBACK_H 

#include "ICallback.h" 
#include <iostream> 

namespace rpcpp 
{ 
class SampleCallback : public ICallback<double> 
{ 
public: 
    ~SampleCallback() {}; 

    virtual void OnSuccess(double result) 
    { 
     std::cout << "Successfully executed a remote procedure, A + B = " << result << "\r\n\r\n"; 
    } 

    virtual void OnError(std::string error) 
    { 
     std::cout << "Error while executing a remote procedure: " << error << "\r\n\r\n"; 
    } 
}; 
} 

#endif // RPCPP_SAMPLE_CALLBACK_H 

をしかし、私はこれを使用しようとすると、いいので、コンパイル:

rpcpp::SampleCallback sc; 
sic.CalculateMean(15, 28, &sc); // Third argument of this method is expected to be ICallbackBase&. 

次の2つのエラーが生成されます。

"#1"行で "抽象クラスをインスタンス化できません"。 "2番線のSampleCallback &からICallbackBase &"にパラメータ3を変換できません

何が間違っていますか?

+0

あなたはそれを参照がかかりますが、あなたはポインタを渡していると述べました。 –

答えて

1
virtual void OnSuccess(void result) = 0; 

は定義されていません。

+0

これは、非テンプレートベースクラスからの私のテンプレート継承が間違っていることを意味します。テンプレートを作成する適切な方法は、非テンプレートベースから抽象メソッドを継承しますか? – skali

+2

これはテンプレートとは関係ありません。純粋仮想関数を持つクラスは抽象クラスであり、インスタンス化することはできません。派生クラスをインスタンス化するには、基本クラスのすべての純粋仮想関数を定義する必要があります。 –

+0

しかし、私が最初にこれをした理由の全体的な点は、仮想空白OnSuccess(T結果)= 0を持つことです。 inherit(オーバーライド)virtual void OnSuccess(void)= 0;ベースクラスから。 – skali

1

あなたはすべての抽象メソッドの実装されていません。

仮想無効ONSUCCESS(無効結果)= 0;

とCalculateMeanの定義は何ですか?

がONSUCCESSからパラメータを削除します:

virtual void OnSuccess()=0; 

がICallbackにコンストラクタのパラメータを追加します。

template<class T> class ICallBack 
{ 
public: 
    ICallBack(T &result) : result(result) { } 
protected: 
    T &result; 
}; 

非許可するように新しいメソッドを追加します

+0

私は何とか共通のインタフェースを宣言する非テンプレート基本クラスと、インタフェースを 'テンプレート化'するテンプレート派生クラスを持つことができると思っていました。そのため、基本クラスへのポインタを使用してテンプレートインスタンスを保持し、このようなメソッド:ICallbackBase * foo; foo-> OnSuccess(3.54); – skali

1

は、ここで実際の問題を解決する方法を示しますT内部表現にアクセスするためのテンプレートコード:

virtual void *Address() const=0; 
virtual size_t Size() const=0; 
virtual type_info Type() const=0; 

ICallBack<T>でこれらのメソッドを実装します。

void *Address() const { return &result; } 
size_t Size() const { return sizeof(T); } 
type_info Type() const { return typeid(T); } 
関連する問題