0

I am currently trying to understand inheritance in C++, but I am quite confused as to why I can't make a descendant class of my main class return an object of the same type as said descendant class from some operator methods I overloaded.

The classes are defined like this (this is an abridged version):

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};
}

And this is how the methods are defined:

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;

So in this case, both methods should return a copy of the vector + operand, but it doesn't work when I use inheritance. If I remove the first class' virtual methods (Vect) from the file, everything works fine. Otherwise the compiler complains about an invalid covariant return type.

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&);

I tried doing it with a reference, but returning a reference to a temporary object is undefined behaviour as far as I know, and I wish for the methods to return a copy of my object and not directly modify it.

Is there any way to do that?

4

1 回答 1

0

我可以指出的一件事是,您没有按照自己的意愿进行继承。我猜你的意图是Vect用作接口并用Vect_fixe.

但是,由于返回类型不同,它们成为协变返回类型。这种机制需要通过指针或引用返回(因此协变类型可以相互转换)。

如果您打算将Vect其用作所有子类型的通用引用处理程序,那么您确实应该返回引用/指针。

我尝试使用引用来执行此操作,但据我所知,返回对临时对象的引用是未定义的行为,我希望这些方法返回我的对象​​的副本而不是直接修改它。

如果你返回一个引用,你可以使用staticlocal 来延长它的生命周期。

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

不过,终生追随并不是一个好主意。正如@nm 在推荐中所说,继承和复制不能很好地混合,因为重载最终会引入歧义或不可避免但不受欢迎的强制转换。

于 2015-11-28T21:03:45.360 回答