Valhalla Legends Forums Archive | General Programming | Using templates

AuthorMessageTime
iago
Ok, I'm writing a very basic memory management class for c++ (it's for homework, not for fun!) and I'm having a problem with using templates (they are the devil). Anyway, here's the definition of my class:
[code]template<class T> class MemObject[/code]
and later on, I want to send a call to my other class to allocate memory for whatever type of object they requested:
[code]MemObject<class T>::MemObject()
{
   ref = allocateMemory(sizeof(T));

   if(ref == ERROR)
   {
      cout << "Error allocating memory!" << endl;
   }
}[/code]
where ref is just an integer that's used to identify the memory and reference it later. My problem is that sizeof(T) causes a compile error, "r:\My Projects\C\School\cs216a4\memObject.cpp(20): error C2027: use of undefined type 'T'"

Obviously, I'm not using this template thing right, but I'm hoping somebody could tell me what I'm doing wrong :)

Thanks!
-iago
April 5, 2003, 7:30 PM
K
[code]
template <class T>
MemObject<T>::MemObject()
{
ref = allocateMemory(sizeof(T));

if(ref == ERROR)
{
cout << "Error allocating memory!" << endl;
}
}
[/code]

You need to include the template declaration at the function level as well.
April 5, 2003, 8:11 PM
iago
[quote author=K link=board=5;threadid=956;start=0#msg7124 date=1049573462]
[code]
template <class T>
MemObject<T>::MemObject()
{
ref = allocateMemory(sizeof(T));

if(ref == ERROR)
{
cout << "Error allocating memory!" << endl;
}
}
[/code]

You need to include the template declaration at the function level as well.
[/quote]

Using exactly your code:
"r:\My Projects\C\School\cs216a4\memObject.cpp(19): error C2365: 'T' : redefinition; previous definition was a 'template parameter'"
April 5, 2003, 8:39 PM
K
I'm not getting that error. Here's what my code looks like.

[code]
// my test class
template <class T>
class MemObj
{
public:
int ref;
MemObj();

};


template <class T>
MemObj<T>::MemObj()
{
    ref = allocateMemory(sizeof(T));

   if(ref == ERROR)
   {
    cout << "Error allocating memory!" << endl;
    }
}
[/code]
April 5, 2003, 8:51 PM
Zakath
Yeah...the way K is doing it is the correct way. That error you're getting is really strange.
April 5, 2003, 8:54 PM
iago
I had this:
[code]
// my test class
template <class T>
class MemObj
{
public:
int ref;
MemObj();

};


template <class T>
MemObj<class T>::MemObj()
{
    ref = allocateMemory(sizeof(T));

   if(ref == ERROR)
   {
    cout << "Error allocating memory!" << endl;
    }
}
[/code]

And it wasn't working. What a kick in the ass! :-)

*applauds
April 5, 2003, 8:55 PM
iago
Ok, NOW this is pissing me off. Here is my main function:
[code]#include <iostream>
#include <string>
#include "memObject.h"
#include <math.h>
#include <stdio.h>
using namespace std;


struct testStruct
{
int value;
double d;
};

int main( int argc, char *argv[] )
{
   MemObject <testStruct> test;
}[/code]

This is from MemObject.h:
[code]template<class T> class MemObject
{
private:
// reference to our object in memory
    // (equivolant to my "index")
Ref ref;
// used to tell us if this object is containing in another object of the same type (only)
//MemObject<T> const *parent;

public:
// This function will allocate and create an object. The data must be set using operator->.
// If there isn't enough room, garbage collection will be initiated. An error message will be printed
// there's still no room following the collection.
// The parameter is used to track linked structures; automatically set if you have nothing to track.
MemObject( MemObject<T> const *theParent = NULL );

// This function will guarantee that the reference to our object is removed when we go out of context.
// This will occur when we exit a function -- this object disappears and hence our reference.
~MemObject();
[.......]
[/code]

And this is how they're defined in my .cpp file:
[code]// This function will allocate and create an object. The data must be set using operator->.
// If there isn't enough room, garbage collection will be initiated. An error message will be printed
// there's still no room following the collection.
// The parameter is used to track linked structures; automatically set if you have nothing to track.
template <class T> MemObject<T>::MemObject( MemObject<T> const *theParent )
{
   ref = allocateMemory(sizeof(T));

   if(ref == ERROR)
   {
      cout << "Error allocating memory!" << endl;
   }
}

// This function will guarantee that the reference to our object is removed when we go out of context.
// This will occur when we exit a function -- this object disappears and hence our reference.
MemObject<class T>::~MemObject()
{
   deleteMemory(ref);
}
[.....][/code]

Here are my errors:
[quote]cs216a4 error LNK2019: unresolved external symbol "public: __thiscall MemObject<struct testStruct>::~MemObject<struct testStruct>(void)" (??1?$MemObject@UtestStruct@@@@QAE@XZ) referenced in function _main
cs216a4 error LNK2019: unresolved external symbol "public: __thiscall MemObject<struct testStruct>::MemObject<struct testStruct>(class MemObject<struct testStruct> const *)" (??0?$MemObject@UtestStruct@@@@QAE@PBV0@@Z) referenced in function _main
cs216a4 fatal error LNK1120: 2 unresolved externals
[/quote]

Clearly, it doesn't think I've defined my contructor or destructor. If I try to add any other functions, it doesn't think I've defined them either. It actually seems like it's completely ignoring my .cpp file, but it's in the same directory and it generates MemObject.obj.

What I'm thinking is that I'm making the same mistake on all the function definitions, but I'm not sure what that mistake is. Any help would be appreciated :)
April 5, 2003, 10:32 PM
Skywing
[quote author=iago link=board=5;threadid=956;start=0#msg7142 date=1049581963]
Ok, NOW this is pissing me off. Here is my main function:
...
Clearly, it doesn't think I've defined my contructor or destructor. If I try to add any other functions, it doesn't think I've defined them either. It actually seems like it's completely ignoring my .cpp file, but it's in the same directory and it generates MemObject.obj.

What I'm thinking is that I'm making the same mistake on all the function definitions, but I'm not sure what that mistake is. Any help would be appreciated :)
[/quote]Template definitions must be in every translation unit compiled, unless the export keyword is used. Note that there are almost no C++ compilers which support the export keyword.
April 5, 2003, 11:02 PM
K
You need to fix your deconstructor the same way you fixed the constructor:

[code]
template <class T>
MemObject<T>::~MemObject()
{
// ...
}
[/code]
April 5, 2003, 11:03 PM
Zakath
Uhh...iago, you aren't CALLING the constructor when you create the object.

Should be:
[code]MemObject<TestStruct> test( NULL );
[/code]
or
[code]MemObject<TestStruct> *test;
test = new MemObject<TestStruct>( NULL );
[/code]
You get the idea?
April 6, 2003, 12:41 AM
iago
[quote author=Zakath link=board=5;threadid=956;start=0#msg7155 date=1049589681]
Uhh...iago, you aren't CALLING the constructor when you create the object.

Should be:
[code]MemObject<TestStruct> test( NULL );
[/code]
or
[code]MemObject<TestStruct> *test;
test = new MemObject<TestStruct>( NULL );
[/code]
You get the idea?
[/quote]

Lies! When it's created on the stack, it's automatically called with the default constructor, I'm almost positive
April 6, 2003, 1:38 AM
Yoni
Zakath lies. iago's constructor, although it has a parameter, is considered a default constructor because all the parameters have a default value.
April 6, 2003, 2:08 AM
Zakath
Hmm...

Nevermind then, seems I'm wrong :P
April 6, 2003, 3:28 AM

Search