[英]inheritance and “invalid covariant return type” error on operator overloading
我有以下表示数值数组的类
class Array {
protected :
double *data; // this will hold the data of the array
int n; // number of elements in the array
public :
virtual Array operator+ ( double value ) const {
// return a new array with the argument added to each element
}
// other declarations follow here...
};
以及从前一个继承的另一个类,并为每个元素添加一个布尔掩码
class MaskedArray : public Array {
private :
bool *mask; // this holds the boolean mask of the array
public :
MaskedArray operator+ ( double value ) const {
// return a new MaskedArray with the argument added to each element
}
// other declarations follow here...
}
当我尝试编译时,出现错误“无效的协变量返回类型”,这是正常现象,因为两个类中的两个重载运算符都具有相同的签名。
我可以通过引用而不是按值传递继承的类的重载运算符的参数来解决此问题,因为这会更改函数的签名,同时为两个类保留相同的接口。 但是我觉得这不是很干净,如果我想从MaskedArray继承怎么办? 我将面临同样的问题。
我希望能够在我的客户代码中写这样的东西
Array array;
// populate array here
Array array2 = array + 1.0;
MaskedArray maskedArray;
// populate maskedArray here
MaskedArray maskedArray2 = maskedArray + 1.0
有没有比我的“ hack”更优雅的方法来实现这一目标?
协变意味着重写的虚函数的返回类型是从基类函数的返回类型继承的。
但是:尽管C ++通常支持协方差,但是该标准仅在返回指针或引用时才允许协方差。 operator+
按值返回,这就是为什么会出现编译器错误。 这不是特定于运算符,而是适用于每个功能。
删除virtual
关键字将消除编译器错误。 但是,如果要这样做,请记住,将operator+
应用于实际引用MaskedArray
的Array
引用或指针MaskedArray
返回一个Array
(因此不包含mask
成员。如果将其MaskedArray
转换为MaskedArray
则原始mask
会丢失)。 。
解决您问题的一种方法是使用遏制而不是继承:
class MaskedArray {
private :
Array array;
bool *mask; // this holds the boolean mask of the array
public :
MaskedArray operator+ ( double value ) const {
// return a new MaskedArray with the argument added to each element
}
// delegate public functions
}
当然,现在MaskedArray不能使用Array的受保护成员(在很多情况下,这是一件好事),必须委托公共接口。
首先,您报告的关于协变结果的错误与提供的代码不一致 。
它仅出现在虚拟成员函数中,在我编写此代码时,在所提供的代码中没有。
不要在将来通过询问有什么错你真正的代码 ,并提出一些由幻想码再浪费时间了。
无论如何,请治愈:在您的真实代码中 ,只需删除单词virtual
。
另外,建议:使用std::vector
来保存数据并注意分配,复制和释放。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.