下面是一些有代表性的代码,它们得到了我遇到的错误:
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参数的数据对象,因此该表将提供一个函数,该函数打印它持有的所有数据的名称列表。这样,我就可以拥有处理所有这些表对象的通用代码,以及只处理一种类型的表的专用代码。
发布于 2012-11-05 21:15:22
很多事情都是错的:
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];
}
// ...
};发布于 2016-05-13 04:09:30
“无效的协变返回类型”实际上是由于您试图更改getData()的返回类型而导致的。虽然返回类型不是函数标识符的一部分,但它仍然受到一些限制。任何覆盖某个基类的方法都应该具有类似的行为。也就是说,虚方法实现将尝试向上转换到Data,以便为从Table* (而不是DerviedTable*)的角度调用getData()的客户端返回一个有效指针。这可以与DerviedTable::getData(int)上下文中的(Data*)myData[index]进行比较。
这正是编译器的困惑之处。
class DerivedData : Data
{
};这个声明说DervidedData私有继承了Data 。也就是说,DerviedData的任何客户端都不“知道”它实际上是一个Data。这也使得为DerviedData* getData() override生成代码变得不可能,因为从DeviedTable::getData(int)无法向上转换到Data。
为了让这个错误消失,你可以让继承对公共可见:
class DerivedData : public Data
{
};或者交个朋友
class DerivedData : Data
{
friend class DerivedTable;
};尽管这种设计仍然是一个有问题的主题。
https://stackoverflow.com/questions/13232853
复制相似问题