2012-03-11 115 views
0

我有一個非模板抽象基類,用於爲了能夠引用基類型,因爲未專用的模板類型不能用作方法參數。C++ HowTo:從抽象專用模板繼承的非模板類

#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_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 

最後,可以通過從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&. 

它產生以下兩個錯誤:

「can not instantiate abstract class」in line#1。 符合#2

「不能從SampleCallback &轉換參數3 ICallbackBase &」我在做什麼錯?

+0

你說這需要一個參考,但你傳遞一個指針。 – 2012-03-11 17:26:05

回答

1
virtual void OnSuccess(void result) = 0; 

從未被定義。

+0

這意味着我的模板從非模板基類繼承是錯誤的,那麼使模板繼承非模板基類的抽象方法的正確方法是什麼? – skali 2012-03-11 17:22:10

+2

這與模板無關。具有純虛函數的類是抽象類,不能實例化。只有在基類中定義了所有純虛函數的情況下,才能實例化派生類。 – 2012-03-11 17:24:29

+0

但是,爲什麼我首先做到這一點的關鍵是要虛擬無效OnSuccess(T結果)= 0;繼承(覆蓋)虛擬無效OnSuccess(無效)= 0;來自基類。 – skali 2012-03-11 18:10:03

1

您沒有實現每個抽象方法:

虛擬無效的onSuccess(無效結果)= 0;

CalculateMean的定義是什麼?

+0

我認爲我可以以某種方式擁有一個聲明通用接口的非模板基類和一個模板派生類,它可以「模板化」接口,以便我可以使用指向基類的指針來存放模板實例並調用它們像這樣的方法:ICallbackBase * foo; foo->的onSuccess(3.54); – skali 2012-03-11 18:12:30

1

這裏是如何解決實際的問題:

從的onSuccess刪除參數:

virtual void OnSuccess()=0; 

添加一個構造函數參數ICallback:

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

添加新的方法,以使非模板代碼訪問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); }