我正在为我的容器类创建一个基类,因此我可以维护一致的接口。它目前看起来像这样:
template <typename Datatype>
class BaseClass
{
public:
virtual Datatype Foo() = 0;
virtual Datatype Bar() = 0;
};
template <typename Datatype>
class DerivedClass: public BaseClass<Datatype>
{
public:
virtual Datatype Foo()
{
}
virtual Datatype Bar()
{
}
};
但是,对于某些派生类,Foo()
和Bar()
可能需要彼此具有不同的返回类型。如果基类中没有每个不同返回类型的模板参数,我如何为派生类提供一些改变这种东西的空间?
编辑:
派生类使用的类型可能完全不同且不变。实际上,除了方法名称之外,派生类不能保证有任何共同点。
答案 0 :(得分:6)
提供专门针对您需要不同结果的情况的特质。
template <typename Datatype>
struct BaseTraits
{
typedef Datatype FooResult;
typedef Datatype BarResult;
};
template <typename Datatype, typename Traits = BaseTraits<Datatype> >
class BaseClass
{
public:
virtual Traits::FooResult Foo() = 0;
virtual Traits::BarResult Bar() = 0;
};
答案 1 :(得分:3)
如果您提前知道潜在类型的数量,可以通过向基类模板添加其他类型来扩展您所拥有的类型......
template <typename FOO_TYPE,typename BAR_TYPE>
class BaseClass
{
public:
virtual FOO_TYPE Foo() = 0;
virtual BAR_TYPE Bar() = 0;
};
template <typename FOO_TYPE,typename BAR_TYPE>
class DerivedClass: public BaseClass<FOO_TYPE,BAR_TYPE>
{
public:
virtual FOO_TYPE Foo() { }
virtual BAR_TYPE Bar() { }
};
如果您有多种类型,这可能会失控。
答案 2 :(得分:1)
如果返回类型是共变体,可以更改它们,或者您可以编写某种转换函数,并且有real_bar
或类似的东西。
答案 3 :(得分:1)
traits可能有所帮助。 C++ Templates - The Complete Guide一书提供了一个示例,在标题为特征和策略类的章节中对此进行了说明。它有一个使用累加器返回不同类型的例子。
编辑:我可以看到AProgrammer已经举了一个例子
答案 4 :(得分:1)
return
不同的数据类型是不可能的。唯一的方法是制作方法template
,因为virtual
方法不能是模板,所以方法是限制的。
答案 5 :(得分:1)
#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T, typename R = T>
class base
{
public:
virtual R foo()
{
cout << "foo(): data type = " << typeid(T).name() << endl; return R();
}
virtual R bar()
{
cout << "bar(): return type = " << typeid(R).name() << endl; return R();
}
};
int main()
{
base<int> b;
base<int, long> b1;
b.foo(); b.bar();
b1.foo(); b1.bar();
cout << typeid(b).name() << endl;
cout << typeid(b1).name() << endl;
return 0;
}
上述程序返回以下内容:
使用g++
:
$ ./rettypetemplate
foo(): data type = i
bar(): return type = i
foo(): data type = i
bar(): return type = l
4baseIiiE
4baseIilE
使用Visual Studio 2005 cl.exe
:
C:\Program Files\Microsoft Visual Studio 8\VC>rettypetemplate.exe
foo(): data type = int
bar(): return type = int
foo(): data type = int
bar(): return type = long
class base<int,int>
class base<int,long>
尽管此示例显示了如何执行此操作,但AProgrammer给出的答案显示了使用特征处理它的好方法。上面的示例适用于基本数据类型,但不适用于用户定义的类型。要处理用户定义的类型,特征是要走的路。请参阅Jossutis的"The C++ Template" book或“Modern C++ design”以了解有关特征的更多信息。