类似类的C ++类模板

时间:2013-03-19 20:31:49

标签: c++ oop templates

我有一个socket数据类型类,用于从套接字流中读取和解析一个值(也可以用于文件)。
让我的班级为mc_double

class mc_double {
    private:
           double value;
    public:
           bool read(socket);
           write(double);
}

实际课程更复杂,但这是原则。现在,我需要从流中解析float。 Float类似于double,因此已经实现int。无法合并此类定义,所有doubleintfloat都会以某种方式模板化?

这就是我的意思:

 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_intmc_floatmc_double
我找到了官方的C ++模板文档,但我只想出了问题的最后一部分 - 我可以创建一个接受多种数据类型的函数。其余的似乎并不那么容易。

2 个答案:

答案 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_doublemc_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' */ }
};