By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,290 Members | 1,363 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,290 IT Pros & Developers. It's quick & easy.

Subclassing a template causes problems

P: 1
Hi! I am writing a program in which I need to keep track of how many objects of a given class exists at a time. The task is to do it using templates. The objects to be counted are of the class Note:
Expand|Select|Wrap|Line Numbers
  1. class Note : public Countable<Note> {
  2. private:
  3. ...
  4. public:
  5. Note();
  6. Note(double points, int time);
  7. Note(double points, string time);
  8. ~Note();
  9. ...
  10. };
Where Countable template is given as:

Expand|Select|Wrap|Line Numbers
  1. template<typename T> class Countable {
  2.     protected:
  3.         static int _currentCounter;
  4.     public:
  5.         Countable();
  6.         Countable(const Countable& c);
  7.         virtual ~Countable();
  8.         static int currentCounter();
  9. };
  10.  
  11. template<typename T> int Countable<T>::_currentCounter = 0;
  12. template<typename T> int Countable<T>::_allCounter = 0;
The Countable template is implemented as:

Expand|Select|Wrap|Line Numbers
  1. template<typename T> Countable<T>::Countable() {
  2.     ++_currentCounter;
  3. }
  4.  
  5. template<typename T> Countable<T>::Countable(const Countable& c) {
  6.     ++_currentCounter;
  7. }
  8.  
  9. template<typename T> Countable<T>::~Countable() {
  10.     --_currentCounter;
  11. }
  12.  
  13. template<typename T> int Countable<T>::currentCounter()  {
  14.     return _currentCounter;
  15. }

For Node class the constructors all call superclass constructors:
Expand|Select|Wrap|Line Numbers
  1. Note::Note() : Countable<Note>() {
  2.     points = 0;
  3.     time = 0;
  4. }
and similarly for other constructors. The ~Note() destructor is empty
Expand|Select|Wrap|Line Numbers
  1. Note::~Note() {}
The task was to modify a previous program and add this option - to count the Node objects. Earlier the whole program was working fine, but now, after introducing Countable and subclassing it by Note I get linker errors like:

Expand|Select|Wrap|Line Numbers
  1. Note.o: In function `Note::Note(not-in-charge)()':
  2. Note.cpp:(.text+0xbcd): undefined reference to `Countable<Note>::Countable(not-in-charge)()'
  3. Note.o: In function `Note::Note(in-charge)(double, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
  4. Note.cpp:(.text+0xd1b): undefined reference to `Countable<Note>::Countable(not-in-charge)()'
  5. Note.cpp:(.text+0xd88): undefined reference to `Countable<Note>::~Countable (not-in-charge)()'
  6. Note.o: In function `Note::~Note (not-in-charge)()':
  7. Note.cpp:(.text+0xdaa): undefined reference to `Countable<Note>::~Countable (not-in-charge)()'
And so on, wich [not-in-charge] errors. What does that mean? Is there something wrong with calling these constructors and destructors?
The Note objects are always created as Note - no class "knows" in any way that Note is a subclass of Countable. Maybe here lies a mistake - should I create the objects in some other way? Thanks for any help.

PS. The task *has* to be solved using such form of template subclassing...
Nov 6 '06 #1
Share this question for a faster answer!
Share on Google+

Post your reply

Sign in to post your reply or Sign up for a free account.