views:

74

answers:

3

My base class:

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

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

Derived template class:

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

I had another issue with this code (answered in another post), but currently I'm wrestling with the fact that if I try to run this, I get

Undefined symbols: "Element::plus(Element const&)", referenced from:
vtable for Vectorin main.o
"Element::Element()", referenced from:
Vector::Vector()in main.o
Vector::Vector(double const&, double const&, double const&)in main.o
"Element::minus(Element const&)", referenced from:
vtable for Vectorin main.o
"typeinfo for Element", referenced from:
typeinfo for Vectorin main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

Is this because the derived template class isn't housed in the same file as the base class, and that's causing compiler issues (similar to how I had to define the entire Vector class in the header file)?

I'm fairly new to C++, and still reading up on what vtables are and how they work, but I can't quite figure this out yet.

+1  A: 

This really has nothing to do with Vector. You declare methods like virtual Element& plus(const Element&) and Element::Element() in Element.h, but you have to define them somewhere, presumably in Element.cc. If you've done that and you're still getting this error, it almost certainly means that you're not linking Element.o into your executable, so the linker simply doesn't know what to put in when Vector (or anything else) invokes these methods.

Beta
Fantastic – I didn't know I had to actually define functions, I thought I could get by simply by declaring them. Wonderful!
Nick Sweet
+3  A: 

If I understand well, you want to have an abstract "Element", and derive "Vector" from "Element". In that case, you should remove your "Element" constructor, and declare "plus" and "minus" to be pure virtual by adding "= 0" at the end of the declaration. Your destructor is fine, though.

That's all the error message is about: as you declared a constructor and some methods in Element, and you end up calling them, the linker looks for them.

I've got the feeling that you would want your Vector class to implement "plus" and "minus" on a Vector, and not on an abstract Element, though. This way, you would not need the static cast. You'd also avoid a world of pain with massive risks of slicing with your return types.

small_duck
Yeah, I'll be playing around with that – I'm just getting into the hang of inheritance, and I'm not quite sure I need a static cast. I'll be trying different ways to make it work.
Nick Sweet
+1  A: 

I think the compiler/linker means it when it tells you Undefined symbols: "Element::plus(Element const&)" . These symbols (plus and minus for Element) have been declared but they have not been defined.

Alexandros Gezerlis
As above – it's fixed!
Nick Sweet