У меня есть базовый класс под названием Элемент, производный класс под названием Вектор, и я пытаюсь переопределить две виртуальных функции от Элемента в Векторе.
//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;
}
Я думал, что смысл полиморфизма наследования - то, что ссылка на производный класс является практически тем же как ссылкой на базовый класс. Почему я должен перейти через эти обручи?
компилятор говорит очевидное: базовый класс 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;
}
Обратите внимание: если вы вернете указатель таким образом, у вас может возникнуть проблема с утечкой памяти.
Могу ли я определить свои виртуальные функции так, чтобы вместо этого они принимали 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, а не вызывать исключение.
Тем не менее, наследование, вполне возможно, является неправильным инструментом для работы здесь: не совсем ясно, каков ваш реальный вариант использования для этого.