Jump to content
  • Advertisement
Sign in to follow this  
D3DXVECTOR3

Template class inherit = unresolved external symbols

This topic is 4428 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

I'm just learned about template classes and im having some trouble with the implementation. Some of my classes look like this:
#define _MyClass (MyClass::Instance());

// header
class MyClass
{
public:
	MyClass();
	~MyClass();

	static MyClass *Instance();

	...

private:
	static MyClass *_instance;

	...
};

//source
MyClass* MyClass::_instance = NULL;

MyClass* MyClass::Instance()
{
  if (!_instance)
    _instance = new MyClass;
  return _instance;
}




now I can use it like _MyClass->... so i thought if i could make a class template CInstance (see below) and inherit it when i want it to instead of writing the same piece of code several times. // header
template <class T>
class CInstance
{
public:
	CInstance();
	~CInstance();
	static T* Instance();

protected:
	static T* _instance;

};




// source
template <class T>
T* CInstance<T>::_instance = NULL;

template <class T>
T* CInstance<T>::Instance()
{
  if (!_instance)
    _instance = new T;
  return _instance;
}

template <class T>
CInstance<T>::CInstance()
{
}

template <class T>
CInstance<T>::~CInstance()
{
}




so far so good (i think), next step: inherit:
class Test: public CInstance<Test>
{
public:
	void DoSomething(void)
	{
	
	};

};

#define _Test (CInstance<Test>::Instance())





... but when I do _Test->DoSomething(); i get an unresolved external symbol: unresolved external symbol "public: static class Test * __cdecl CInstance<class Test>::Instance(void)" (?Instance@?$CInstance@VTest@@@@SAPAVTest@@XZ) any idea's? thanks :) edit: im using VC++ 2005 express [Edited by - D3DXVECTOR3 on July 7, 2006 2:03:56 PM]

Share this post


Link to post
Share on other sites
Advertisement
Unless your compiler supports the export keyword, and I'm willing to bet that yours doesn't, then you can't put the definition of a template in a separate source file without explicit instantiation for specific types. Without explicit instantiation, the complete definition of the template needs to be available at point of instantiation, which means, in effect, that the definition needs to go into the header. (Or an inline file of some sort, etc.)

For more details see these articles: "Export" Restrictions, Part 1 and "Export" Restrictions, Part 2.

Share this post


Link to post
Share on other sites
You problems are:

0) templates must go in header files. They cannot go in source files until support for the "export" keyword is increased. Until then just put your template implementation under the template declaration.

1)
Quote:

_MyClass


All names beginning with an underscore followed by a capital letter are reserved for the compilers use. Same applies for double underscores.

2) using a #define like that is pointless. Why not just make a global and be done with it? It wont even compile as is - #define betterNameForMyclass (MyClass::Instance()); will expand such lines as

betterNameForMyclass->foo();

into:

betterNameForMyclass;->foo();

4)
Quote:

if (!_instance)
_instance = new CInstance<T>;

Perhaps you meant:

if (!_instance)
_instance = new T();

3) Many singletons are often a sign of poor design

Share this post


Link to post
Share on other sites
moving the function definition to the header file worked, many thx Driv3MeFar :)

I still would like to know how I would fix it by using "extern"

Share this post


Link to post
Share on other sites
Quote:
Original post by D3DXVECTOR3
moving the function definition to the header file worked, many thx Driv3MeFar :)

I still would like to know how I would fix it by using "extern"


Do you mean "extern" or "export"?

Extern is used when dealing with global variables defined in other files. Export is the keyword that, according the the C++ standard, will let you have template prototypes and definitions in separate files. Currently, most compilers (MSVS all versions, borland, maybe GCC, but I don't know it well enought to say for sure) do not support export correctly/at all. The only compiler I know of that does is comeau.

If it were to be implemented correctly, you would use it like so.

[Edited by - Driv3MeFar on July 7, 2006 4:53:49 PM]

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!