【问题标题】:virtual function with user-defined-type vector具有用户定义类型向量的虚函数
【发布时间】:2023-04-07 03:41:01
【问题描述】:

我想定义一个带有结构变量向量的抽象基类,以及一个由派生类实现的虚函数:

class TestFather {

private:
    struct myStruct
    {
        // struct definition
    };
    vector<myStruct> myStructVect;

public:
    virtual vector<myStruct> get_myStructVect() = 0;
};

但是当我写派生类的时候:

#include "TestFather.h"

class TestSon : public TestFather{

private:
    struct myStruct
    {
        // struct definition
    };
    vector<myStruct> myStructVect;

public:
    vector<myStruct> get_myStructVect();
};

我得到这个错误:

invalid covariant return type for ‘virtual std::vector<ProvaSon::myStruct, std::allocator<ProvaSon::myStruct> > ProvaSon::get_myStructVect()’

我是在做错事,还是在尝试做一些语言禁止的事情?

【问题讨论】:

  • 为什么要重新定义两次 myStruct?
  • 好吧,那是“人为错误”:)

标签: c++ templates implementation virtual-functions


【解决方案1】:

这两个myStruct 类型完全不相关。这意味着您正在尝试覆盖 TestFather::get_myStructVect() 并让它返回完全不同的类型。这是不允许的。

【讨论】:

  • 最后一点不正确——因为他返回的是它们的向量,而不是指向它们的指针。
  • 是的 - 只是因为他们有相同的名字并不意味着你是一样的!
【解决方案2】:

您不必重新定义TestSon 中的结构,您也不能这样做。 fatherptr-&gt;get_myStructVect 的调用者静态返回 vector&lt;TestFather::myStruct&gt;,因此编译器禁止你像这样重写基类函数,因为动态返回的对象可能与 vector&lt;TestFather::myStruct&gt; 不兼容(谁知道你在 @987654325 中放入了什么@ 以及 vector 与基类向量的行为有何不同?)。

至于允许的区别,C++只允许派生类返回类型是基类返回类型的派生类,并且只允许返回类型是指针或引用。

【讨论】:

    【解决方案3】:

    这是禁止的。因为您在派生类中重新定义了 myStruct,所以 vector 在派生类中与基类中的类型不同。它们是两个不同的 myStruct。

    您只能将该虚函数的返回类型更改为继承自基类中声明的返回类型的内容。但是 vector<:mystruct> 不继承自 vector<:mystruct>

    【讨论】:

      【解决方案4】:

      vector&lt;myStruct&gt; 但是由于您在子类中更改了 myStruct 它实际上是两种不同的类型,因此这两个函数中的每一个都认为它返回不同的类型。这仅适用于类型与包含函数的类的实际类型相关的协变类型。

      请注意,您可能不应该在这里按值返回类属性向量。

      我不知道你真正打算做什么,但是如果嵌套结构是两个不同的东西,那么它们真的不应该有相同的名称(如果它们相同,请不要重新定义它) .我的第一个直觉反应是,也许亲子关系在这里不合适。您是否考虑过其他选择?如果您确实需要在子项中返回不同的类型而父项不知道,那么您不能使用虚拟接口来执行此操作。你应该给函数起不同的名字,这样你就知道返回类型应该是什么。

      更多关于你的目标的细节可以提供更好的答案。

      【讨论】:

      • 我的目标是定义多个具有共同数据结构的子类,所以我认为接口的选择是合适的。我希望这些类在 same 数据上做不同的事情,并且我想对这些数据的结构施加某种形式的限制(因此我选择了接口)。
      【解决方案5】:

      在您的示例中,重复的私有结构有点奇怪。下面的编译很好,例如:

      类TestFather {

      protected:
          struct myStruct
          {
              // struct definition
          };
          vector<myStruct> myStructVect;
      
      public:
          virtual vector<myStruct> get_myStructVect() = 0;
      };
      
      class TestSon : public TestFather{
      
      
      
      public:
          vector<myStruct> get_myStructVect();
      };
      
      int main(int argc, char**argv)
      {
         TestSon testSon;
      }
      

      注意将 private 替换为 protected,允许派生类访问父结构定义和 myStructVect 存储。

      【讨论】:

      • 不,它没有,g++ 返回“未定义的对 `vtable for TestSon' 的引用”。但是,“受保护”是一个有用的提示。
      猜你喜欢
      • 1970-01-01
      • 2012-10-17
      • 2019-05-25
      • 1970-01-01
      • 1970-01-01
      • 2019-01-02
      • 2017-11-15
      • 1970-01-01
      • 2015-02-13
      相关资源
      最近更新 更多