协变返回类型无效

Jon*_*rce 3 c++ inheritance class

以下是一些代表性的代码,它可以解决我遇到的错误:

class Data
{
};

class Table
{
  virtual std::vector<Data*> getData() = 0;
  virtual void putData(Data* dataItem) = 0;
  virtual Data* getData(int index) = 0;
};

class DerivedData : Data
{
};

class DerivedTable : Table
{
  std::vector<DerivedData*> getData() { return myData; } // invalid covariant return type
  void putData(DerivedData *dataItem) { myData.push_back(dataItem); }
  virtual DerivedData* getData(int index) { return myData[index]; } // invalid covariant return type

  std::vector<DerivedData*> myData;
};
Run Code Online (Sandbox Code Playgroud)

首先,我不太明白为什么putData的重写对于更改的参数感到满意,但是我无法更改getData的返回类型,尽管我很欣赏这是我可以从更多内容中获得理解的东西.读.

其次,我的主要问题是,如何更改此代码以使其工作.我的基本目标是允许存储和控制数据对象的多个"表"对象.虽然每个数据对象将共享一些共同的东西,但是表格将控制和使用这些差异.例如,一个表可能包含具有name参数的数据对象,因此该表将提供一个函数,该函数打印它所拥有的数据的所有名称的列表.通过这种方式,我可以使用适用于所有这些表对象的通用代码,以及仅使用一种类型的表操作的专用代码.

Ker*_* SB 5

很多事情都错了:

  1. 这两个版本putData只是不同的,无关的重载.对于在C++中重写虚函数,没有"逆变参数类型"这样的东西(即使有,它也会反过来!!).将关键字添加override到派生函数以使编译器产生错误.

  2. 类模板不像您想象的那样工作.如果template <typename T> class Foo是一个类模板,然后Foo<X>Foo<Y>完全不同的,unlrelated类,无论XY以任何方式有关.


正如@Beta所说,你可能只是一个简单std::vector<std::unique_ptr<Data>>的主数据结构.但无论如何,如果你真的必须有一些层次结构,这里有一个可能的"解决方案":

#include <memory>
#include <vector>

struct Data { virtual ~Data() { } };

struct Table
{
    virtual ~Table() { }

    typedef std::unique_ptr<Data> data_ptr;
    typedef std::vector<data_ptr> dataset_type;

    virtual dataset_type & getData() = 0;
    virtual void putData(data_ptr dp) = 0;
    virtual Data & getData(std::size_t n) = 0;
};

class DerivedTable : public Table
{
    dataset_type myData;

public:

    virtual void putData(data_ptr p) override
    {
        myData.push_back(std::move(p));
    }

    Data & getData(std::size_t n) override
    {
        return *myData[n];
    }

    // ...
};
Run Code Online (Sandbox Code Playgroud)