[英]Invalid covariant return type
以下是一些代表性的代码,它可以解决我遇到的错误:
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;
};
首先,我不太明白为什么putData的覆盖对改变的参数感到满意,但是我无法改变getData的返回类型,尽管我很欣赏这是我可以从更多内容中获得理解的东西。读。
其次,我的主要问题是,如何更改此代码以使其工作。 我的基本目标是允许存储和控制数据对象的多个“表”对象。 虽然每个数据对象将共享一些共同的东西,但是表格将控制和使用这些差异。 例如,一个表可能包含具有name参数的数据对象,因此该表将提供一个函数,该函数打印其所拥有的数据的所有名称的列表。 通过这种方式,我可以使用适用于所有这些表对象的通用代码,以及仅使用一种类型的表操作的专用代码。
很多事情都错了:
putData
的两个版本只是不同的,无关的重载。 对于在C ++中重写虚函数,没有“逆变参数类型”这样的东西(即使有,它也会反过来!!)。 将关键字override
添加到派生函数以使编译器产生错误。
类模板不像您想象的那样工作。 如果template <typename T> class Foo
是一个类模板,那么Foo<X>
和Foo<Y>
是完全不同的,不相关的类,无论X
和Y
是否以任何方式相关。
正如@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];
}
// ...
};
“无效的协变返回类型”实际上是由于您尝试更改getData()
的返回类型而引起的。 虽然返回类型不是函数标识符的一部分,但它仍然受到一些限制。 覆盖某些基类的任何方法都应该表现得相似。 即虚拟方法实现将尝试向Data
进行向上转换,以便为从Table*
(而非DerviedTable*
)的角度调用getData()
客户端返回有效指针。 这可以与DerviedTable::getData(int)
上下文中的(Data*)myData[index]
进行比较。
这就是编译器混淆的确切位置。
class DerivedData : Data
{
};
该声明说, DervidedData
继承Data
私人 。 即DerviedData
任何客户端都不“知道”它实际上它是一个Data
。 这也使DerviedData* getData() override
的代码生成无法DerviedData* getData() override
因为从DeviedTable::getData(int)
无法访问向上转换为Data
。
为了使该错误消失,你可以将继承visbile公开:
class DerivedData : public Data
{
};
或者交个朋友
class DerivedData : Data
{
friend class DerivedTable;
};
虽然这个设计仍然是一个问题的主题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.