【问题标题】:Forward declare nested stucture in base class [duplicate]在基类中前向声明嵌套结构[重复]
【发布时间】:2015-12-29 19:57:40
【问题描述】:

假设我有一个基础抽象类:

class Foo {
public:
    struct FooStruct;
    virtual FooStruct *DoFoo() = 0;
};

现在我想在Bar 中实现DoFoo 并在其中定义FooStruct

class Bar: public Foo {
public:
    struct FooStruct {
        int data;
    };
    FooStruct *DoFoo() {
        FooStruct *fs = new FooStruct;
        fs->data = 42;
        return fs;
    }
};

但是,g++(就我而言)将Foo::FooStructBar::FooStruct 识别为两个不同的结构,并且会抱怨invalid covariant type ...,因为我重新定义了方法的返回类型。

我该如何解决这个问题?

【问题讨论】:

  • 你也需要定义Foo::FooStruct。您定义Bar::FooStruct 的事实无关紧要。
  • 返回值需要一个通用的基类。

标签: c++ oop


【解决方案1】:

我猜你的目的是这样做:

Foo * my_foo = new Bar();
FooStruct * my_result = my_foo->DoFoo();

问题是现在要使用my_result,你必须知道它隐含的struct是由Bar创建的。因此,您应该将返回的struct externaly 定义为Foo

【讨论】:

    【解决方案2】:

    您正在尝试创建一个不适合 C++ 类型系统的怪物。

    想象一下有人试图多态地使用Foo 指针:

    Foo* ptr = .... ; //getting the value from somewhere, e.g. an API call
    ??? result = ptr->DoFoo();
    

    返回值的类型是什么?编译器不知道。

    为要返回的结构使用通用基类。前向声明不会削减它。

    【讨论】:

      【解决方案3】:

      你不能做你看似想做的事。在整个层次结构中,虚函数应该具有相同的静态返回类型,而 Foo::FooStruct 与 Bar::FooStruct 无关。您似乎渴望的是以下内容:

      // In Foo.h
      struct FooStruct { virtual ~FooStruct() = default; }
      
      class Foo {
      public:
          virtual FooStruct* DoFoo() = 0;
          virtual ~Foo() = default;
      };
      
      // In Bar.h
      struct DerivedFooStruct : FooStruct { };
      struct Bar : public Foo {
          FooStruct* DoFoo() { return new DerivedFooStruct(); } // Never mind memory mgmt
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-31
        • 2023-03-25
        相关资源
        最近更新 更多