Как заставить подкласс возвращать объект (копию) самого себя в виртуальном методе

В настоящее время я пытаюсь понять наследование в 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

Решение

Я мог бы отметить одну вещь: вы не делаете наследование так, как хотели. Я могу догадаться, что вы намеревались использовать Vect в качестве интерфейса и переопределить его Vect_fixe,

Но, поскольку возвращаемые типы различны, они становятся ковариантными возвращаемыми типами. Этот механизм требует возврата по указателю или по ссылке (поэтому ковариантные типы можно приводить друг к другу).

Если вы собираетесь использовать Vect как общий обработчик ссылок для всех его подтипов, тогда вы действительно должны возвращать ссылки / указатели.

Я попытался сделать это с помощью ссылки, но возвращение ссылки на временный объект, насколько я знаю, является неопределенным поведением, и я хочу, чтобы методы возвращали копию моего объекта, а не модифицировали его напрямую.

Если вы вернете ссылку, вы можете продлить срок ее службы с помощью static местный.

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. Как отмечается в комментариях, наследование и копирование плохо сочетаются, потому что перегрузка в конечном итоге привнесет неясности или неизбежные, но нежелательные приведения.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector