Как вы возвращаете указатель на базовый класс с виртуальной функцией? - PullRequest
1 голос
/ 17 июня 2010

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

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

но я всегда получаю

ошибка: в элементе const class нет элемента с именем 'x'

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

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

РЕДАКТИРОВАТЬ: Попытка static_cast (как предложено ниже) не решила мою проблему - или у меня неправильный синтаксис для него.Я пробовал статическое приведение двумя способами, которые я мог себе представить, и теперь моя ошибка:> error: в элементе const class нет элемента с именем 'x'

Мой обновленный код: // sum templateElement & Vector :: plus (const Element & v) const {Element * ret = static_cast *> (оператор new ((x + vx), (y + vy), (z + vz)));возврат * ret;}

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

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

Ответы [ 2 ]

1 голос
/ 18 июня 2010

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

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 голос
/ 17 июня 2010

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

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

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

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

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

Вы можете использовать dynamic_cast, если вы точно не знаете, что у вас есть Vector:

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...