我有一个socket数据类型类,用于从套接字流中读取和解析一个值(也可以用于文件)。
让我的班级为mc_double
:
class mc_double {
private:
double value;
public:
bool read(socket);
write(double);
}
实际课程更复杂,但这是原则。现在,我需要从流中解析float
。 Float类似于double,因此已经实现int
。无法合并此类定义,所有double
,int
和float
都会以某种方式模板化?
这就是我的意思:
class mc_<typename = double or int or float> {
private:
typename value;
public:
bool read(socket);
write(typename);
}
然后,某些方法将被单独定义为mc_double::method()
其他方法对于所有类型都是相同的:mc_typename::general_method()
。此外,对于一些人,我只需要对代码进行微小的更改:
typename mc_typename::return_value() {
return val;
}
或构造函数:
mc_typename::mc_typename(<int, long, char, double> number) {
val = (typename)number;
}
结果应为三个类 - mc_int
,mc_float
和mc_double
。
我找到了官方的C ++模板文档,但我只想出了问题的最后一部分 - 我可以创建一个接受多种数据类型的函数。其余的似乎并不那么容易。
答案 0 :(得分:3)
您可以将您的班级设为班级模板:
template<typename T, bool base = true>
class mc {
protected:
T value;
public:
bool read(socket);
write(T);
};
此类将包含所有类型T
通用的成员函数。然后,您可以针对不同类型单独专门化这个类模板和让它们继承自mc<T, true>
:
template<>
class mc<double, true> : public mc<double, false> {
public:
// Member functions for double only...
};
template<>
class mc<int, true> : public mc<int, false> {
public:
// Member functions for int only...
};
如果您希望派生类访问它们,请确保将主类模板的非公共成员数据设为protected
。
然后你可以这样实例化它们:
mc<double> m;
mc<int> m;
// ...
如果您确实想使用mc_double
和mc_int
名称,那么您可以:
a)为它们创建类型别名:
typedef mc<double> mc_double;
typedef mc<int> mc_int;
b)将类模板的设计更改为不使用特化并且只有一个模板参数,并独立创建派生类:
template<typename T>
class mc {
protected:
T value;
public:
bool read(socket);
write(T);
};
class mc_double : public mc<double> {
public:
// Member functions for double only...
};
class mc_int: public mc<int> {
public:
// Member functions for int only...
};
答案 1 :(得分:1)
您可以在类定义中使用模板,如下所示:
template <typename T>
class mc
{
public:
bool write(T _val);
private:
T mVal;
};
但你不能轻易地专注于某些方法,而不是基于T类型的其他方法(即,你必须专门化整个类,而不仅仅是一种方法)。您可以使用某种继承层次结构解决此问题,其中无论类型如何都是相同的方法在基础中,而特化是在派生类中。所以保持上述(假设write
是一个不改变的)并创建:
class mc_double : public mc<double>
{
public:
void doSomethingSpecific() { /* code specific for 'doubles' */ }
};