Вызов функции из производного класса шаблона - PullRequest
3 голосов
/ 20 июня 2010

Мой базовый класс:

//Element.h
class Element
{
public:
Element();
virtual ~Element(){}; // not sure if I need this

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

Производный шаблон класса:

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

template <class T>
class Vector: public Element {
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& plus(const Element&) const;
Element& minus(const Element&) const;
...
};
...

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

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

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

Неопределенные символы: «Элемент :: плюс (Элемент const &)», на который ссылаются:
vtable для Vectorin main.o
«Элемент :: Элемент ()», на который ссылаются:
Vector :: Vector () в main.o
Vector :: Vector (двойной констант &, двойной констант &, двойной констант &) в main.o
"Элемент :: минус (Элемент const &)", ссылка с которого:
vtable для Vectorin main.o
"typeinfo для элемента", ссылка на которую:
typeinfo для Vectorin main.o
ld: символ (ы) не найдены
collect2: ld вернул 1 статус выхода

Это потому, что производный класс шаблона не размещен в том же файле, что и базовый класс, и это вызывает проблемы с компилятором (аналогично тому, как я должен был определить весь класс Vector в заголовочном файле)?

Я довольно новичок в C ++ и до сих пор читаю, что такое vtables и как они работают, но я пока не могу понять это.

Ответы [ 3 ]

3 голосов
/ 20 июня 2010

Если я хорошо понимаю, вы хотите иметь абстрактный «Элемент» и получить «Вектор» из «Элемента». В этом случае вам следует удалить конструктор «Элемент» и объявить «плюс» и «минус» чисто виртуальными, добавив «= 0» в конце объявления. С твоим деструктором все в порядке.

Вот и все сообщение об ошибке: так как вы объявили конструктор и некоторые методы в Element, и в итоге вы вызываете их, компоновщик ищет их.

У меня такое ощущение, что вы хотите, чтобы ваш класс Vector реализовывал "плюс" и "минус" на векторе, а не на абстрактном элементе. Таким образом, вам не понадобится статическое приведение. Вы также избежите мира боли с огромным риском нарезки с вашими типами возврата.

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

Я думаю, что компилятор / компоновщик имеет это в виду, когда говорит вам Undefined symbols: "Element::plus(Element const&)".Эти символы (плюс и минус для Элемента) были объявлены, но они не были определены.

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

Это действительно не имеет ничего общего с Vector. Вы объявляете методы, такие как virtual Element& plus(const Element&) и Element::Element() в Element.h, но вам необходимо определить их где-то, предположительно в Element.cc. Если вы сделали это и все еще получаете эту ошибку, это почти наверняка означает, что вы не связываете Element.o со своим исполняемым файлом, поэтому компоновщик просто не знает, что вставить, когда Vector (или все остальное) вызывает эти методы.

...