【问题标题】:C++ Problem: Class Promotion using derived classC++ 问题:使用派生类进行类提升
【发布时间】:2011-09-22 10:07:36
【问题描述】:

我有一个从 Float32_base 派生的 Float32 类

类 Float32_base { 民众: // 构造函数 Float32_base(float x) : value(x) {}; Float32_base(void) : value(0) {}; 运算符 float32(void) {返回值;}; Float32_base 运算符 =(float x) {value = x;返回 *this;}; Float32_base 运算符 +(float x) const { 返回值 + x;}; 受保护: 浮点值; } 类 Float32:公共 Float32_base { 民众: 浮动泰德(){ 返回值 + .01; } } int main() { Float32 x, y, z; x = 1; y = 2; // 不会编译! z = (x + y).Tad(); // 编译成功 z = ((Float32)(x + y)).Tad(); }

问题是 + 运算符返回一个 Float32_base 并且 Tad() 不在该类中。但是“x”和“y”是 Float32 的。

有没有一种方法可以让我在第一行编译代码,而不必像在下一行那样使用类型转换?

【问题讨论】:

  • Tad()Float32 类中是私有的。您是否在某处错过了public?单独的Float32Float32_base 类有什么意义?在我看来,您可以将所有内容放在一个 Float32 类中,并让它以完全相同的方式工作。
  • 在这种情况下,您可以简单地在Float32 中覆盖operator+。想必你的真实情况比这复杂?
  • 类“Float32”旨在特定于平台。 Tad() 在不同的平台上是不同的。我想为浮动可以做的所有一般事情使用基类“Float32_base”,但将特定于平台的代码放在“Float32”中。
  • 你的代码还能用吗?你的operator+ 有签名Float32_base(float),那么如何添加x + yfloat 没有演员表运算符?!另外,float32 是什么?
  • 很抱歉,如果这篇文章中的代码错误或不完整。它确实有效,但在这里展示的太多了。

标签: c++ inheritance polymorphism class-design


【解决方案1】:

您可以在操作的结果类型上模板化FLoat32_base 类。

或者将所有内容都放在一个类中(可能是最好的),将少数特定于平台的操作委托给特定于平台的功能。

干杯,

【讨论】:

    【解决方案2】:

    如果只需要一级深度继承,可以使用CRTP

    template <typename T>
    struct A
    {
      T
      operator+ (const A&)
      { return T (); }
    };
    
    struct B : A <B>
    {
      void
      lol ()
      { }
    };
    
    int
    main ()
    {
      B a, b;
      (a + b).lol ();
    }
    

    【讨论】:

    • 看起来这就是我要找的魔法酱!我创建了一个模板 FloatT_base 然后将其用作基类:Class Float32_T: FloatT_base 和 Voilà!
    • @MichaelFitzpatrick 我建议您将其标记为已接受。
    【解决方案3】:

    您必须重写 operator+ 方法,因为 operator+ 的返回类型定义为 Float32_base。您可以通过协方差来做到这一点,并使方法虚拟化。然后覆盖子类中的方法(您可能只调用超类中的方法)。

    您也可以通过模板来做到这一点,但如果您不熟悉模板,我不建议您深入研究它。本质上,您将按照您已经做过的方式定义虚函数,但不是返回 Float32_base,而是返回您的模板类型。 (只要您的模板类型是子类,那么 C++ 应该具有良好的逆变性)。您的子类将使用子类的模板扩展基类。

    【讨论】:

    • 我添加了代码:“Float32 operator +(float32 x) const { return Float32_base::operator+(x);};”到 Float32{} 并且有效。只是这违背了目的。如果我必须对每个方法都这样做,我可能还没有基类。
    猜你喜欢
    • 2010-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-12
    • 2015-09-23
    • 1970-01-01
    • 2017-12-13
    • 1970-01-01
    相关资源
    最近更新 更多