多态(继承)和值类型

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多态(继承)和值类型相关的知识,希望对你有一定的参考价值。

我有一堆类型,qazxsw poi,qazxsw poi,qazxsw poi等,代表一个单位的价值。我希望他们有

  • 价值语义:例如有效地不可变,不必担心内存分配,而且
  • 多态性:我可以返回一个PixelMeasure类型的对象,并且可以对它进行操作而不知道它是什么特定的类型。我还希望能够将多个不同的PointMeasures放入容器中。

看来这些在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,希望有一个标准版本即将出现。

或者,您可以编写一个更具体的区分联合,提供一个很好的特定多态风格的接口

以上是关于多态(继承)和值类型的主要内容,如果未能解决你的问题,请参考以下文章

继承--方法覆盖--多态

java 代码片段

继承与多态

四. Java继承和多态5. instanceof 运算符

Java初级开发面试被问到封装多态继承直接原地撸代码,要我明天入职滴滴?

多态与继承