help with template classes

V

Victor Hannak

This is my first try at using a template class, and I am getting linker
errors that I can't figure out:

[Linker Error] Unresolved external
'ShapeStackClass<CircleClass>::GetStackSize()' referenced from
C:\PROGRAM1\MYCLASS.OBJ.
[Linker Error] Unresolved external
'ShapeStackClass<SquareClass>::GetStackSize()' referenced from
C:\PROGRAM1\MYCLASS.OBJ.

This is how I have set up my template class:

ShapeStackClass.h
--------------------
template <class ShapeType>
class ShapeStackClass {
public:
ShapeStackClass(unsigned short MaxStackSizeIn);
~ShapeStackClass();
unsigned short GetStackSize();
....

ShapeStackClass.c
--------------------
#include "ShapeStackClass.h"
template <class ShapeType>
ShapeStackClass<ShapeType>::ShapeStackClass(unsigned short MaxStackSizeIn) {
StackSize = 0;
MaxStackSize = MaxStackSizeIn;
}
template <class ShapeType>
ShapeStackClass<ShapeType>::~ShapeStackClass() {
EmptyStack();
}
template <class ShapeType>
unsigned short ShapeStackClass<ShapeType>::GetStackSize() {
return(StackSize);
}
....
I am creating and using this class as follows where Circles and Squares are
derived from the Shape class :

MyClass.h
-----------
#include "ShapeStackClass.h"
class MyClass {
public:
MyClass();
~MyClass();
unsigned short MyClass::GetSize();
private:
ShapeStackClass<CircleClass> *CircleStack;
ShapeStackClass<SquareClass> *SquareStack;
}

MyClass.c
-----------
MyClass::MyClass() {
CircleStack = new ShapeStackClass<CircleClass>(5);
SquareStack = new ShapeStackClass<SquareClass>(5);
}

MyClass::~MyClass() {
delete CircleStack;
delete SquareStack;
}

unsigned short MyClass::GetSize() {
return(CircleStack->GetStackSize()+SquareStack->GetStackSize());
}

What am I doing wrong?
 
A

Artie Gold

Victor said:
This is my first try at using a template class, and I am getting linker
errors that I can't figure out:

[Linker Error] Unresolved external
'ShapeStackClass<CircleClass>::GetStackSize()' referenced from
C:\PROGRAM1\MYCLASS.OBJ.
[Linker Error] Unresolved external
'ShapeStackClass<SquareClass>::GetStackSize()' referenced from
C:\PROGRAM1\MYCLASS.OBJ.

In (virtually all) available C++ compilers, templated code needs to
be visible in any translation unit in which it is used.

IOW, put the definitions (which you have in ShapeStackClass.c) in
the header.

HTH,
--ag
 
K

Kevin Goodsell

Victor said:
MyClass.h
-----------
#include "ShapeStackClass.h"
class MyClass {
public:
MyClass();
~MyClass();
unsigned short MyClass::GetSize();
private:
ShapeStackClass<CircleClass> *CircleStack;
ShapeStackClass<SquareClass> *SquareStack;

Why are you using pointers here instead of just declaring actual objects?
}

MyClass.c

What happens if

1) 'new' cannot provide enough memory and throws an exception?
2) The ShapeStackClass constructor throws an exception?

Explicit dynamic memory management creates all kinds of problems. That's
why it's better to not use 'new' until you have to, and then use things
like smart pointers to make sure the memory will be correctly handled if
things go south.

-Kevin
 
J

Josephine Schafer

Artie Gold said:
Victor said:
This is my first try at using a template class, and I am getting linker
errors that I can't figure out:

[Linker Error] Unresolved external
'ShapeStackClass<CircleClass>::GetStackSize()' referenced from
C:\PROGRAM1\MYCLASS.OBJ.
[Linker Error] Unresolved external
'ShapeStackClass<SquareClass>::GetStackSize()' referenced from
C:\PROGRAM1\MYCLASS.OBJ.

In (virtually all) available C++ compilers, templated code needs to
be visible in any translation unit in which it is used.

IOW, put the definitions (which you have in ShapeStackClass.c) in
the header.

I think this should be a part of the FAQ, now that it gets asked so frequently.
Just to add out here that until our compilers support the export keyword we
have to live with the inclusive compilation model for templates i.e each
translation unit
that uses templated code has to include the template definition.

Just wondering as to what all complexities compiler vendors are facing to
support the export keyword ...
May be someone can give some insight.
 
M

Mike Wahler

Josephine Schafer said:
Artie Gold said:
Victor said:
This is my first try at using a template class, and I am getting linker
errors that I can't figure out:

[Linker Error] Unresolved external
'ShapeStackClass<CircleClass>::GetStackSize()' referenced from
C:\PROGRAM1\MYCLASS.OBJ.
[Linker Error] Unresolved external
'ShapeStackClass<SquareClass>::GetStackSize()' referenced from
C:\PROGRAM1\MYCLASS.OBJ.

In (virtually all) available C++ compilers, templated code needs to
be visible in any translation unit in which it is used.

IOW, put the definitions (which you have in ShapeStackClass.c) in
the header.

I think this should be a part of the FAQ,

It is. See items 34.12 and 34.13
now that it gets asked so frequently.
Just to add out here that until our compilers support the export keyword we
have to live with the inclusive compilation model for templates i.e each
translation unit
that uses templated code has to include the template definition.

Just wondering as to what all complexities compiler vendors are facing to
support the export keyword ...
May be someone can give some insight.

http://www.parashift.com/c++-faq-lite/containers-and-templates.html#faq-34.1
2

http://www.comeaucomputing.com/techtalk/templates/
(See item 5)

-Mike
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,143
Messages
2,570,822
Members
47,368
Latest member
michaelsmithh

Latest Threads

Top