2012-03-11 105 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); }