Jump to content
  • Advertisement
Sign in to follow this  
Phex

SOLVED: Dynamic Template List

This topic is 4831 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Thank you for the help! I am referring to VC++. Hello, I have a maybe rather easy problem but I tryed to solve it for the last few hours and I have absolutely no idea what I am doing wrong: I use a template class in my current program which is really neccessary, but there are two things I cant get to work: 1) I get a linker error when I compile my program. I already looked at different Tutorials and they tell me to put an instance of my template class into the source file. like: template class cList<cElement>; I did this, but now I get a warning ("(4660) template class instance already defined") - my only solution was to ignore it with #pragma warning (disable: 4660), but that does not seem correct. Is there another way to remove the linker error? 2) The template class itself is a dynamic list which should be able to add and remove items that are saved with pointers pointing to each other. The list saves the First and the Last items' addresses and every item is connected to the Next and the Previous item of the list with pointers (I posted my code below). This is not perfect, but very usefull for what I want to do. My problem is: I can add items to my template List, but I cannot remove items. Somehow it seems like the item I want to delete is not affected. What am I doing wrong? Here is the relevant part of my code:
//Generic List Class (in a header file)
template <class T>
class cList
{
private:
	T *First;	//First Element
	T *Last;	//Last Element

public:
	T *Add();			//Add Element: works!
	void Remove(T *obj);		//Remove Element with specified Address: doesnt work!
	cList(){ First = Last = 0 };	//Ctor
};


//Example for an Element class that could be used for the List (in a header file)
class cElement
{
public:
	cElement *Next;	//Next Element
	cElement *Prev;	//Previous Element
	cElement(){ Next = Prev = 0 };	//Ctor
};


//Remove function (in a source file)
template <class T>
void cList<T>::Remove( T *obj )
{
	//Check if Address of Element which should be removed is valid
	if( !obj )
		return;

	//Reassign Connections
	if( obj->Prev )
		obj->Prev->Next = obj->Next;
	if( obj->Next )
		obj->Next->Prev = obj->Prev;	

	//Delete Element
	delete obj;
	obj = 0;
}



Thank you for your help! rgds, Phex [Edited by - Phex on May 24, 2005 2:56:11 PM]

Share this post


Link to post
Share on other sites
Advertisement
1) I get a linker error when I compile my program.

About a missing cList::Remove function, I presume? [smile]

//Remove function (in a source file)

Function template definitions and class template member function definition need to go into the header file.

I already looked at different Tutorials and they tell me to put an instance of my template class into the source file. like: template class cList<cElement>;

Right, the other option, if you don't want to put the function in the header file is to specify, in the source file that contains the member function definitions, which versions of the class template you're going to use in your program, so that the compiler actually goes and generate the corresponding member functions. So if you write class cList<cElement>; (no template keyword), the compiler will know that it needs to generate the member functions for that version of the class template. You just need to make sure that you add that for each and every version you will ever want to use, and make sure they actually are in the same source file as where the member functions are defined (since the compiler actually needs the source code AND to know which version of the class template it is going to use at the same time).

Which is why putting the member functions in the the header file makes things easier, as the compiler always has everything it needs.

And no, in the case of function templates and class template member functions, just as with inline functions, putting the definition in a header file (i.e. causing it to be multiply defined, once in each translation unit that includes the header file), is not an error. For "normal" non-inline, non-template functions, it is an error.

2) The template class itself is a dynamic list which should be able to add and remove items that are saved with pointers pointing to each other.

C++ already has a list class template, std::list defined in the <list> standard header, use it.

This is not perfect, but very usefull for what I want to do.

I gather you aren't then just trying to create a list class for learning purposes. You therefore have no excuse not to use std::list. [evil]

Somehow it seems like the item I want to delete is not affected.

Well, the obj = 0; statement won't affect the original pointer variable, only the local copy in your Remove function. The rest should work normally.


Share this post


Link to post
Share on other sites
Thank you for the quick answer!

1) I tried to put the template function definitions into a header file, but I still get a linker error: error LNK2001. When I put template class cList<cElement>; in a source file, it works again together with a warning.

2) I will look closer at the predefined list class if I cant get any further, but it seems too complex for my purposes. Maybe it would be easier to ask how I can create an operation that does what obj = 0 is meant to do?

Share this post


Link to post
Share on other sites
Quote:
Original post by Phex
1) I tried to put the template function definitions into a header file, but I still get a linker error: error LNK2001.


Ok, what precisely is the error message?

Quote:
2) I will look closer at the predefined list class if I cant get any further, but it seems too complex for my purposes.


It's just a stupid linked list, how can it be 'too complex' [smile] If you're referring to its interface, it's just that it is unfamiliar. All the standard C++ containers have a similar interface, you would do well to learn it, it'll save you much trouble down the road.

Quote:
Maybe it would be easier to ask how I can create an operation that does what obj = 0 is meant to do?


Simply pass obj by reference instead of by value:

template <class T> void cList<T>::Remove( T*& obj )

Any modifications of the obj variable will be reflected on to the pointer you really passed to the function.

Share this post


Link to post
Share on other sites
1) My compilation log is in German, but it says something like
Linking...
sourcefile.obj : error LNK2001: Non-resolved external symbol "public: class cElement * __thiscall cList<cElement>::Add(void)" (?Add@?$cList@VcElement@@@@QAEPAVcElement@@XZ)
fatal error LNK1120: 1 non-resolved external reference

when I try to execute cList::Add().

2) Remove() works perfectly now!

Share this post


Link to post
Share on other sites
Quote:
Original post by CodeMunkie
Probably because Add() is defined, but not implemented.


You mean declared, but not defined, of course ;)

Share this post


Link to post
Share on other sites
It's hard to say what the state of your code is at this point, but the function definitions have to be included with the header file, in the case of templates (until there is widespread support of the export keyword, at least). There are a few ways to do it - you can put the function definitions right inside the class definition


template< typename T>
struct SomeStruct
{
void SomeMethod()
{
//function definition
}
};


or:


template< typename T>
struct SomeStruct
{
void SomeMethod();
};

template< typename T>
void SomeStruct< T>::SomeMethod()
{
//function definition
}


or:

in SomeStruct.h


template< typename T>
struct SomeStruct
{
void SomeMethod();
};

#include "SomeStruct.cpp"


in SomeStruct.cpp NOTE: don't compile this source file into your project


template< typename T>
void SomeStruct< T>::SomeMethod()
{
//function definition
}


I personally prefer the first method, but to each his own.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!