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

recurring template problem

P: n/a
I've been reading (and using the examples in) Thinking in C++ (vol 2).

One of the things that the author shows you can do with templates is
the following:

#include <iostream>
using namespace std;

template<class T>
class Counted
{
static int count;
public:
Counted() { ++count; }
Counted(const Counted<T>&) { ++count; }
~Counted() { --count; }
static int getCount() { return count; }

};

template<class T>
int Counted<T>::count = 0;

// Curious class definitions
class CountedClass : public Counted<CountedClass> {};
class CountedClass2 : public Counted<CountedClass2> {};

int main()
{
CountedClass a;
cout << CountedClass::getCount() << endl; // 1
CountedClass b;
cout << CountedClass::getCount() << endl; // 2
CountedClass2 c;
cout << CountedClass2::getCount() << endl; // 1 (!)
} ///:~

I've tried adapting this idea to the following class that I've
used/created to try out some other things (Below is the almost working
example).

Header file:
[code]
#ifndef ID_CLASS_H
#define ID_CLASS_H

#include <map>

// magic number defines
#define NOT_A_VALID_ID -1

template<class T>
class ID_Class
{
private:
static std::map<int, int> ID_Map;
int ID_Value;

void DecrementReference();
void IncrementReference();

public:
// Only reason to ever NOT use the default constructor is when you
read
// the IDs from a source instead of creating new IDs.
ID_Class(int tID);
ID_Class();
~ID_Class();

ID_Class(const ID_Class<T>& Right);
ID_Class<T>& operator= (const ID_Class<T>& Right);

int Get_ID() const;

// Test/debug functions below this comment
void DumpMap() const;
};

#endif

cpp:
#include "ID_Class.h"

#include <stdexcept>
#include <ostream>
// note that #include <map> has been defined in the header. This is
needed
// for the static definition used there.

using std::cout;
using std::overflow_error;
using std::bad_alloc;
using std::pair;
using std::map;

template<class T>
map<int, int> ID_Class<T>::ID_Map;

// private functions
template<class T>
void ID_Class<T>::DecrementReference()
{
map<int,int>::iterator it = ID_Map.find(ID_Value);
--(it->second);
if ( it->second < 1)
{
ID_Map.erase(it);
}
}

template<class T>
void ID_Class<T>::IncrementReference()
{
map<int,int>::iterator it = ID_Map.find(ID_Value);
++(it->second);
if (it->second < 1)
{
throw overflow_error("To many copies exist");
}
}

// public functions
template<class T>
ID_Class<T>::ID_Class(int tID)
{
ID_Value = tID;
if ((ID_Map.insert(pair<int,int>(ID_Value,1))).second == false)
{
throw bad_alloc();
}
}

template<class T>
ID_Class<T>::ID_Class()
{
ID_Value = 1;
map<int,int>::const_iterator it (ID_Map.begin());
map<int,int>::const_iterator itEnd (ID_Map.end());

while(( it != itEnd) && (ID_Value == (*it).first))
{
++ID_Value;
++it;
}
if (ID_Value < 1)
{
throw overflow_error("Requested negative ID");
}
if ((ID_Map.insert(pair<int,int>(ID_Value,1))).second == false)
{
throw bad_alloc();
}
}

template<class T>
ID_Class<T>::~ID_Class()
{
DecrementReference();
}

template<class T>
ID_Class<T>::ID_Class(const ID_Class<T>& Right)
{
ID_Value = Right.ID_Value;
IncrementReference();
}

template<class T>
ID_Class<T>& ID_Class<T>::operator= (const ID_Class<T>& Right)
{
DecrementReference();
ID_Value = Right.ID_Value;
IncrementReference();
return *this;
}

template<class T>
int ID_Class<T>::Get_ID() const
{
return ID_Value;
}

// Test/Debug functions below this comment
template<class T>
void ID_Class<T>::DumpMap() const
{
map<int,int>::const_iterator it (ID_Map.begin());
map<int,int>::const_iterator itEnd (ID_Map.end());
while (it != itEnd)
{
cout << "ID " << (*it).first << " Has " << (*it).second << " copies"
<< endl;
++it;
}
}

main.cpp:

#include "ID_Class.h"
#include <iostream>

using namespace std
class MainID : public ID_Class<MainID>
{
};

int main( int argc, char* argv[])
{
// MainID TestID;

char t;
cin.get(t);
return(0);
};

I know that I'm missing something here since the code will compile
without a warning but when I uncomment // Main TestID; I get
unresolved externals (ctor & dtor). The question is what is is that am
I missing? What rules am I trying to break? And is there a way around
the problem?
Jul 22 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a

"velthuijsen" <ve*********@hotmail.com> wrote in message
news:e5**************************@posting.google.c om...
I've been reading (and using the examples in) Thinking in C++ (vol 2).

One of the things that the author shows you can do with templates is
the following:
[snip]
I know that I'm missing something here since the code will compile
without a warning but when I uncomment // Main TestID; I get
unresolved externals (ctor & dtor). The question is what is is that am
I missing? What rules am I trying to break? And is there a way around
the problem?


It's the old, old problem. Put all your template code in the header file,
that's where it belongs. I'm surprised Bruce Eckel didn't explain that in
his book, but here it is in the FAQ.

http://www.parashift.com/c++-faq-lit...templates.html

questions 34.12 to 34.15

john
Jul 22 '05 #2

P: n/a

"velthuijsen" <ve*********@hotmail.com> wrote in message
news:e5**************************@posting.google.c om...
I've been reading (and using the examples in) Thinking in C++ (vol 2).

One of the things that the author shows you can do with templates is
the following:
[snip]
I know that I'm missing something here since the code will compile
without a warning but when I uncomment // Main TestID; I get
unresolved externals (ctor & dtor). The question is what is is that am
I missing? What rules am I trying to break? And is there a way around
the problem?


It's the old, old problem. Put all your template code in the header file,
that's where it belongs. I'm surprised Bruce Eckel didn't explain that in
his book, but here it is in the FAQ.

http://www.parashift.com/c++-faq-lit...templates.html

questions 34.12 to 34.15

john
Jul 22 '05 #3

P: n/a
"John Harrison" <jo*************@hotmail.com> wrote in message news:<c4*************@ID-196037.news.uni-berlin.de>...
"velthuijsen" <ve*********@hotmail.com> wrote in message
news:e5**************************@posting.google.c om...
I've been reading (and using the examples in) Thinking in C++ (vol 2).

One of the things that the author shows you can do with templates is
the following:
[snip]

I know that I'm missing something here since the code will compile
without a warning but when I uncomment // Main TestID; I get
unresolved externals (ctor & dtor). The question is what is is that am
I missing? What rules am I trying to break? And is there a way around
the problem?


It's the old, old problem. Put all your template code in the header file,
that's where it belongs. I'm surprised Bruce Eckel didn't explain that in
his book, but here it is in the FAQ.


He did. In his first book, chapter 16. Guess this is what I get when I
just copy/paste existing files instead of trying to remember all the
excercises he'd suggested.

http://www.parashift.com/c++-faq-lit...templates.html

questions 34.12 to 34.15

Jul 22 '05 #4

P: n/a
"John Harrison" <jo*************@hotmail.com> wrote in message news:<c4*************@ID-196037.news.uni-berlin.de>...
"velthuijsen" <ve*********@hotmail.com> wrote in message
news:e5**************************@posting.google.c om...
I've been reading (and using the examples in) Thinking in C++ (vol 2).

One of the things that the author shows you can do with templates is
the following:
[snip]

I know that I'm missing something here since the code will compile
without a warning but when I uncomment // Main TestID; I get
unresolved externals (ctor & dtor). The question is what is is that am
I missing? What rules am I trying to break? And is there a way around
the problem?


It's the old, old problem. Put all your template code in the header file,
that's where it belongs. I'm surprised Bruce Eckel didn't explain that in
his book, but here it is in the FAQ.


He did. In his first book, chapter 16. Guess this is what I get when I
just copy/paste existing files instead of trying to remember all the
excercises he'd suggested.

http://www.parashift.com/c++-faq-lit...templates.html

questions 34.12 to 34.15

Jul 22 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.