多态(继承)和值类型
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多态(继承)和值类型相关的知识,希望对你有一定的参考价值。
我有一堆类型,qazxsw poi,qazxsw poi,qazxsw poi等,代表一个单位的价值。我希望他们有
- 价值语义:例如有效地不可变,不必担心内存分配,而且
- 多态性:我可以返回一个
PixelMeasure
类型的对象,并且可以对它进行操作而不知道它是什么特定的类型。我还希望能够将多个不同的PointMeasure
s放入容器中。
看来这些在C ++中是互斥的。对于多态,我需要使用指针或引用。
我看到两个选择:
- 使用智能指针,例如
CentimeterMeasure
。这给了我想要的行为(安全,没有原始指针,但是多态调度)。缺点是: 它很冗长(如果我真的想要,我可以将它隐藏在typedef后面)。 你有内存分配(但代码不是性能关键,而是隐藏起来)。 语义很奇怪 - 我的对象(Measure
)的副本将共享相同的底层指针。我仍然可以假装它具有值语义 - 如果我使接口不可变,那应该没关系。 - 我简单地想过不使用继承(没有公共基类)和通过模板调度 - 但是在这种情况下我需要在编译时知道确切的Measure类型,并且不能将它们放入容器中。
- 我可以完全摆脱这些类,只使用一个类,一个值和一个单位字段 - 但这将不那么灵活,而且使用语法会更糟,所以我宁愿避免这种情况。
有任何想法吗?
答案
你可以使用type-erase,因为正如Sean Parent所说,Measure
。他还有一个介绍shared_ptr
,这可能是你想要的。这背后是同样的想法,例如shared_ptr<PixelMeasure>
。
基本上,您通过内部类中的继承使用子类型多态,以使用以多态方式映射到概念的所有内容。以下是inheritance is the base class of all evil的一个例子:
Value Semantics and Concept Based Polymorphism
现在,您可以将所有内容放入具有greet方法的Greeter对象中。其他示例是boost :: any_iterator或std :: function。
每个Measure值将遭受一次内存分配。
另一答案
您可以使用包含适当的复制构造函数的包装类和指向Measure的指针作为字段。您可能需要将clone方法添加到Measure。
std::function
另一答案
您可以使用变体类型:它避免了动态分配,但使多态分派变得更加复杂。
请参阅Type Erasure with Merged Concepts,希望有一个标准版本即将出现。
或者,您可以编写一个更具体的区分联合,提供一个很好的特定多态风格的接口
以上是关于多态(继承)和值类型的主要内容,如果未能解决你的问题,请参考以下文章