我目前正在尝试理解C ++中的继承,但我很困惑为什么我不能使我的主类的后代类从我重载的一些操作符方法返回与所述后代类相同类型的对象
这些类定义如下(这是一个删节版本):
template <class elem>
class Vect
{
public:
Vect() = default;
virtual Vect operator+(const elem&);
virtual Vect operator-(const elem&);
}
template <class elem, std::size_t taille=10>
class Vect_fixe: public Vect<elem>
{
public:
Vect_fixe() = default;
virtual Vect_fixe operator+(const elem&);
virtual Vect_fixe operator-(const elem&);
private:
elem vecteur[taille] = {0};
}
这就是方法的定义方式:
template <class elem, std::size_t taille>
Vect_fixe<elem,taille> Vect_fixe<elem, taille>::operator+(const elem& operand)
{
Vect_fixe<elem, taille> temp_v;
for (int i=0; i<taille; i++)
{
temp_v[i] = vecteur[i];
temp_v[i] += operand;
}
return temp_v;
}
template <class elem, std::size_t taille>
Vect_fixe<elem,taille> Vect_fixe<elem, taille>::operator-(const elem& operand)
{
Vect_fixe<elem, taille> temp_v;
for (int i=0; i<taille; i++)
{
temp_v[i] = vecteur[i];
temp_v[i] -= operand;
}
return temp_v;
所以在这种情况下,两个方法都应该返回vector +操作数的副本,但是当我使用继承时它不起作用。如果我从文件中删除第一类'虚拟方法(Vect),一切正常。否则编译器会抱怨协变返回类型无效。
main.cpp:88:24: required from here
main.cpp:50:24: error: invalid covariant return type for 'Vect_fixe<elem, taille> Vect_fixe<elem, taille>::operator+(const elem&) [with elem = int; long unsigned int taille = 35ul]'
Vect_fixe<elem,taille> Vect_fixe<elem, taille>::operator+(const elem& operand)
^
In file included from main.cpp:9:0:
Vect.hpp:25:22: error: overriding 'Vect<elem> Vect<elem>::operator+(const elem&) [with elem = int]'
virtual Vect operator+(const elem&);
^
main.cpp:62:24: error: invalid covariant return type for 'Vect_fixe<elem, taille> Vect_fixe<elem, taille>::operator-(const elem&) [with elem = int; long unsigned int taille = 35ul]'
Vect_fixe<elem,taille> Vect_fixe<elem, taille>::operator-(const elem& operand)
^
In file included from main.cpp:9:0:
Vect.hpp:26:22: error: overriding 'Vect<elem> Vect<elem>::operator-(const elem&) [with elem = int]'
virtual Vect operator-(const elem&);
我尝试使用引用,但是据我所知,返回对临时对象的引用是未定义的行为,我希望方法返回我的对象的副本而不是直接修改它。
有没有办法做到这一点?
答案 0 :(得分:0)
我可以指出的一点是,你没有按照自己的意愿继续做继承。我猜你的意图是使用Vect
作为接口并用Vect_fixe
覆盖它。
但是,因为返回类型不同,它们会变成协变返回类型。这种机制需要通过指针或引用返回(因此协变类型可以相互转换)。
如果您打算将Vect
用作其所有子类型的通用引用处理程序,那么您应该真正返回引用/指针。
我尝试使用引用,但是据我所知,返回对临时对象的引用是未定义的行为,我希望方法返回我的对象的副本而不是直接修改它。
如果您返回引用,则可以使用static
local。
int& returnByReference()
{
static int x = 5; // static ensures x doesn't go out of scope when we return it by reference
return x;
}
int value = returnByReference(); // case A -- ok, treated as return by value
const int &cref = returnByValue(); // case C -- ok, the lifetime of return value is extended to the lifetime of cref
不过要追求生活并不是一个好主意。作为@ n.m.在赞扬中说,继承和复制不能很好地混合,因为超载最终会引入含糊不清或不可避免但不受欢迎的演员。