如何在C ++中为同一类定义不同的types
我想有几种types共享相同的实现,但在C ++中仍然是不同的types。
为了用一个简单的例子来说明我的问题,我想为苹果,橘子和香蕉开设一个class级,他们都有相同的操作和相同的实施。 我希望他们有不同的types,因为我想避免types安全性的错误。
class Apple { int p; public: Apple (int p) : p(p) {} int price () const {return p;} } class Banana { int p; public: Banana (int p) : p(p) {} int price () const {return p;} } class Orange ...
为了不重复的代码,它看起来像我可以使用基类水果,并从它inheritance:
class Fruit { int p; public: Fruit (int p) : p(p) {} int price () const {return p;} } class Apple: public Fruit {}; class Banana: public Fruit {}; class Orange: public Fruit {};
但是,构造函数不是inheritance的,我必须重写它们。
是否有任何机制(typedefs,模板,inheritance…),这将允许我轻松拥有不同types的同一类?
一个常见的技术是有一个类模板,其中的模板参数只是作为一个唯一的标记(“标记”),使其成为一个独特的types:
template <typename Tag> class Fruit { int p; public: Fruit(int p) : p(p) { } int price() const { return p; } }; using Apple = Fruit<struct AppleTag>; using Banana = Fruit<struct BananaTag>;
请注意,标签类甚至不需要定义,只需声明一个唯一的types名即可。 这是可行的,因为标签实际上在模板中的任何地方使用 。 你可以在模板参数列表中声明types名称(帽子提示为@ Xeo)。
using
语法是C ++ 11。 如果你坚持使用C ++ 03,请改为:
typedef Fruit<struct AppleTag> Apple;
如果常见的function占用了大量的代码,不幸的是在最终的可执行文件中引入了相当多的重复代码。 这可以通过一个公共的基类实现function,然后有一个从它派生的专门化(你真正实例化)来阻止。
不幸的是,这要求您重新实现所有非可inheritance成员(构造函数,赋值…),这本身会增加一个小的开销 – 所以这只对大类有意义。 这里适用于上面的例子:
// Actual `Fruit` class remains unchanged, except for template declaration template <typename Tag, typename = Tag> class Fruit { /* unchanged */ }; template <typename T> class Fruit<T, T> : public Fruit<T, void> { public: // Should work but doesn't on my compiler: //using Fruit<T, void>::Fruit; Fruit(int p) : Fruit<T, void>(p) { } }; using Apple = Fruit<struct AppleTag>; using Banana = Fruit<struct BananaTag>;
使用模板,并使用每个水果的特征 ,例如:
struct AppleTraits { // define apple specific traits (say, static methods, types etc) static int colour = 0; }; struct OrangeTraits { // define orange specific traits (say, static methods, types etc) static int colour = 1; }; // etc
然后有一个单独的Fruit
类,这是键入这个特质,例如。
template <typename FruitTrait> struct Fruit { // All fruit methods... // Here return the colour from the traits class.. int colour() const { return FruitTrait::colour; } }; // Now use a few typedefs typedef Fruit<AppleTraits> Apple; typedef Fruit<OrangeTraits> Orange;
可能会稍微矫枉过正! ;)
- C ++ 11将允许构造函数inheritance: 使用C ++基类构造函数?
- 否则,您可以使用模板来实现相同的function,例如
template<class Derived> class Fruit;
还有BOOST_STRONG_TYPEDEF 。