Как Вы возвращаете указатель на базовый класс с виртуальной функцией?

У меня есть базовый класс под названием Элемент, производный класс под названием Вектор, и я пытаюсь переопределить две виртуальных функции от Элемента в Векторе.

//element.h
template <class T>
class Element
{
public:
Element();

virtual Element& plus(const Element&);
virtual Element& minus(const Element&);
};

и в другом файле

//Vector.h
#include "Element.h"

template <class T>
class Vector: public Element<T> {
T x, y, z;

public:

//constructors
Vector();
Vector(const T& x, const T& y = 0, const T& z =0);
Vector(const Vector& u);

...

//operations
Element<T>& plus(const Element<T>& v) const;
Element<T>& minus(const Element<T>& v) const;
... 

};

//sum
template <class T>
Element<T>& Vector<T>::plus(const Element<T>& v) const
{
Element<T>* ret = new Vector((x + v.x), (y + v.y), (z + v.z));
return *ret;
}

//difference
template <class T>
Element<T>& Vector<T>::minus(const Element<T>& v) const
{
Vector<T>* ret = new Vector((x - v.x), (y - v.y), (z - v.z));
return *ret;
}

но я всегда добираюсь

ошибка: 'класс константы Элемент' имеет названный 'x' участника

Так, я могу определить свои виртуальные функции для взятия Vector& в качестве аргумента или являюсь там способом для меня получить доступ к элементам данных Вектора через указатель на Элемент?

Я все еще довольно плохо знаком с полиморфизмом наследования к вашему сведению.

Править: Попытка static_cast (как предложено ниже) не решила мою проблему – или у меня есть неправильный синтаксис для него. Я попробовал статический бросок этими двумя способами, которыми я мог вообразить, и теперь моя ошибка> ошибка: 'класс константы Элемент' имеет названный 'x' участника

Мой обновленный код://суммируют шаблон Element& Vector:: плюс (константа Element& v) константа {Элемент* мочат = static_cast*> (новый оператор ((x + v.x), (y + v.y), (z + v.z))); возвратитесь *, мочат;}

//difference 
template <class T> 
Element<T>& Vector<T>::minus(const Element<T>& v) const 
{ 
Element<T>* ret = new Vector<T>(static_cast<Vector*>((x - v.x), (y - v.y), (z - v.z)));
return *ret; 
} 

Я думал, что смысл полиморфизма наследования - то, что ссылка на производный класс является практически тем же как ссылкой на базовый класс. Почему я должен перейти через эти обручи?

1
задан Nick Sweet 17 June 2010 в 05:22
поделиться

2 ответа

компилятор говорит очевидное: базовый класс Element не иметь переменную-член 'x', потому что x объявлен в векторе, а не в элементе. Попробуйте следующее:

Element<T>& plus(const Element<T>& v) const     {
const Vector<T> & vect = dynamic_cast<const Vector<T> &>(v);
Vector<T>* ret = new Vector((x + vect.x), (y + vect.y), (z + vect.z));
return *ret;
}

Обратите внимание: если вы вернете указатель таким образом, у вас может возникнуть проблема с утечкой памяти.

1
ответ дан 2 September 2019 в 23:43
поделиться

Могу ли я определить свои виртуальные функции так, чтобы вместо этого они принимали Vector & в качестве аргумента

Нет; типы параметров должны быть одинаковыми, чтобы функция могла переопределить виртуальную функцию базового класса.

есть ли способ получить доступ к элементам данных вектора через указатель на Element?

Да, но вам нужно привести аргумент Element & к Vector & с использованием static_cast или dynamic_cast .

Вы можете использовать static_cast , только если точно знаете, что аргумент действительно является вектором . Конечно, если вы это знаете, вы можете просто изменить тип параметра на Вектор и .

Вы можете использовать dynamic_cast , если не знаете наверняка, что у вас действительно есть вектор :

const Vector<T>& w = dynamic_cast<const Vector<T>&>(v);

Обратите внимание, что это будет успешным, если аргумент действительно является Vector и в противном случае завершится ошибкой, выбрасывая std :: bad_cast .Вместо этого вы можете приводить указатели (разыменование и прием адресов в зависимости от ситуации), и в этом случае сбои приведут к тому, что приведение будет возвращать значение null, а не вызывать исключение.

Тем не менее, наследование, вполне возможно, является неправильным инструментом для работы здесь: не совсем ясно, каков ваш реальный вариант использования для этого.

1
ответ дан 2 September 2019 в 23:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: