多态性(继承)和值类型 [英] Polymorphism (inheritance) and value types
问题描述
我有一堆类型,PixelMeasure
,PointMeasure
,CentimeterMeasure
等,以一个单位表示一个值.我希望他们有
I have a bunch of types, PixelMeasure
, PointMeasure
, CentimeterMeasure
and so on, that represent a value with a unit. I would like them to have
- 值语义:例如实际上是不变的,不必担心内存分配,并且
- 多态性:我可以返回类型为
Measure
的对象,并且可以对其进行操作,而无需知道其具体的种类.我还希望能够将多个不同的Measure
放入一个容器中.
- value semantics: e.g. effectively immutable, don't have to worry about memory allocation, and
- polymorphism: I can return an object of type
Measure
and can operate on it without knowning what specific kind it is. I would also like to be able to put multiple differentMeasure
s into a container.
似乎这些在C ++中是互斥的.对于多态,我需要使用指针或引用.
It seems these are mutually exclusive in C++. For polymorphism, I need to use pointers or references.
我看到两个选择:
- 使用智能指针,例如
shared_ptr
.这给了我我想要的行为(安全,没有原始指针,而是多态调度).缺点是:- 这很冗长(如果我真的愿意,我可以将它隐藏在typedef后面).
- 您可以在内部进行内存分配(但是代码不是性能至关重要的,并且被隐藏了).
- 语义很混乱-我的对象(
shared_ptr<PixelMeasure>
)的副本将共享相同的基础指针.我仍然可以假装它具有值语义-如果我使接口不可变,那就没关系了.
- Use smart pointers, e.g.
shared_ptr
. This gives me the behavior that I want (safe, no raw pointers, but polymorphic dispatch). The downsides are:- It is verbose (I could hide it behind a typedef if I really wanted).
- You have memory allocation going on beneath the hood (but the code is not performance-critical and it is hidden away).
- The semantics is wierd - a copy of my object (
shared_ptr<PixelMeasure>
) will share the same underlying pointer. I can still pretend it to have value semantics - if I make the interface immutable, it shouldn't matter.
有什么想法吗?
推荐答案
您可以使用类型擦除,因为正如Sean Parent所说,继承是所有邪恶的基类.他也有一个演示文稿价值语义学和基于概念的多态性这可能是您想要的.这是背后相同的想法
std::function
.You can use type-erase because as Sean Parent puts it, inheritance is the base class of all evil. He also has a presentation Value Semantics and Concept Based Polymorphism which is probably what you want. It is the same idea behind e.g.
std::function
.基本上,您可以通过内部类中的继承来使用子类型多态性,以使用多态映射到概念的所有内容.这是来自合并概念的类型擦除的示例:
Basically, you use sub-type polymorphism through inheritance in an internal class to use everything that maps to a concept polymorphically. Here is an example from Type Erasure with Merged Concepts:
class Greeter { public: // Constructor: We can stuff anything into a Greeter costume. template <class T> Greeter(T data) : self_(std::make_shared<Model<T>>(data)) {} // External interface: Just forward the call to the wrapped object. void greet(const std::string &name) const { self_->greet(name); } private: // The abstract base class is hidden under the covers... struct Concept { virtual ~Concept() = default; virtual void greet(const std::string &) const = 0; }; // ... and so are the templates. template <class T> class Model : public Concept { public: Model(T data) : data_(data) {} virtual void greet(const std::string &name) const override { // Forward call to user type. // Requires that T can greet. data_.greet(name); } private: // The user defined Greeter will be stored here. (by value!) T data_; }; // Polymorphic types require dynamic storage. // Here we store our pointer to the Model that holds the users Greeter. std::shared_ptr<const Concept> self_; };
现在,您可以将所有内容放入具有greet方法的Greeter对象中.其他示例是boost :: any_iterator或std :: function.
Now, you can put everything into a Greeter object which has a greet method. Other examples are boost::any_iterator or std::function.
您将为每个Measure值分配一次内存.
You will suffer one memory allocation per Measure value.
这篇关于多态性(继承)和值类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!