How to define different types for the same class in C++(如何在C++中为同一个类定义不同的类型)
问题描述
我想要几种共享相同实现但在 C++ 中仍然是不同类型的类型.
I would like to have several types that share the same implementation but still are of different type in C++.
为了用一个简单的例子来说明我的问题,我想为 Apples、Oranges 和 Bananas 创建一个类,它们都具有相同的操作和相同的实现.我希望它们有不同的类型,因为我想通过类型安全避免错误.
To illustrate my question with a simple example, I would like to have a class for Apples, Oranges and Bananas, all having the same operations and same implementation. I would like them to have different types because I want to avoid errors thanks to type-safety.
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 ...
为了不重复代码,看起来我可以使用基类 Fruit 并继承它:
In order not duplicating code, it looks like I could use a base class Fruit and inherit from it:
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 {};
但是,构造函数不是继承的,我必须重写它们.
But then, the constructors are not inherited and I have to rewrite them.
是否有任何机制(typedef、模板、继承...)可以让我轻松拥有不同类型的同一个类?
Is there any mechanism (typedefs, templates, inheritance...) that would allow me to easily have the same class with different types?
推荐答案
一种常见的技术是拥有一个类模板,其中模板参数仅用作唯一标记(标签")以使其成为唯一类型:>
A common technique is to have a class template where the template argument simply serves as a unique token ("tag") to make it a unique type:
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>;
注意,标签类甚至不需要定义,只要声明一个唯一的类型名称就足够了.这是有效的,因为标签实际上在模板中的任何地方使用.您可以在模板参数列表中声明类型名称inside(给@Xeo 的提示).
Note that the tag classes don’t even need to be defined, it’s enough to declare a unique type name. This works because the tag isn’s actually used anywhere in the template. And you can declare the type name inside the template argument list (hat tip to @Xeo).
using
语法是 C++11.如果您坚持使用 C++03,请改写:
The using
syntax is C++11. If you’re stuck with C++03, write this instead:
typedef Fruit<struct AppleTag> Apple;
<小时>
如果通用功能占用了大量代码,那么不幸的是,这会在最终的可执行文件中引入大量重复代码.这可以通过让一个公共基类实现功能,然后从它派生出一个特化(你实际实例化)来防止.
If the common functionality takes up a lot of code this unfortunately introduces quite a lot of duplicate code in the final executable. This can be prevented by having a common base class implementing the functionality, and then having a specialisation (that you actually instantiate) that derives from it.
不幸的是,这需要您重新实现所有不可继承的成员(构造函数、赋值……),这本身会增加一些开销——因此这仅对大型类有意义.这里应用到上面的例子中:
Unfortunately, that requires you to re-implement all non-inheritable members (constructors, assignment …) which adds a small overhead itself – so this only makes sense for large classes. Here it is applied to the above example:
// 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>;
这篇关于如何在C++中为同一个类定义不同的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何在C++中为同一个类定义不同的类型
- C++ 协变模板 2021-01-01
- 一起使用 MPI 和 OpenCV 时出现分段错误 2022-01-01
- 从python回调到c++的选项 2022-11-16
- Stroustrup 的 Simple_window.h 2022-01-01
- STL 中有 dereference_iterator 吗? 2022-01-01
- 近似搜索的工作原理 2021-01-01
- 与 int by int 相比,为什么执行 float by float 矩阵乘法更快? 2021-01-01
- 如何对自定义类的向量使用std::find()? 2022-11-07
- 使用/clr 时出现 LNK2022 错误 2022-01-01
- 静态初始化顺序失败 2022-01-01