Jump to content
  • Advertisement
Sign in to follow this  
Endar

static initialisation in source files, VC++

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

When you have static data members in a class, you have to add a declaration in a source file that is compiled, right?
#ifndef _IMBASE_CPP_
#define _IMBASE_CPP_

#include "list.h"
#include "IMBase.h"


util::list<IMBase*> IMBase::activeList;		///< The list of active objects (with ref_count > 0)
util::list<IMBase*> IMBase::deadList;		///< The list of dead objects (with ref_count == 0)


#endif



#ifndef _IMBASE_H_
#define _IMBASE_H_

#include "list.h"

/**
 * Provides the basic menmory managment for objects.
 */
class IMBase
{
private:

	static util::list<IMBase*> activeList;		///< The list of active objects (with ref_count > 0)
	static util::list<IMBase*> deadList;		///< The list of dead objects (with ref_count == 0)

	long ref_count;			///< Reference variable

public:

	// functions
};



So, shouldn't this work? I've added the IMBase source file to the project, and the IMBase header is included where it needs to be. Also the list header file is included and the list source file is added to the project. So, theoretically, shouldn't this be working? I'm still getting:
IMBase.obj : error LNK2001: unresolved external symbol 
"public: __thiscall util::list<class IMBase *>::list<class IMBase *>(void)" (??0?$list@PAVIMBase@@@util@@QAE@XZ)
IMBase.obj : error LNK2001: unresolved external symbol 
"public: __thiscall util::list<class IMBase *>::~list<class IMBase *>(void)" (??1?$list@PAVIMBase@@@util@@QAE@XZ)
Debug/test.exe : fatal error LNK1120: 2 unresolved externals


Share this post


Link to post
Share on other sites
Advertisement
I will have to question your use of those include guards on your .CPP file. Try taking those off and recompiling (clean then rebuild). Right now, other than that, your method of declaring them in the .CPP file looks correct to me.

Share this post


Link to post
Share on other sites
The include guards in the source file was habit from a time I didn't use project files properly. [smile]

Nah, it didn't work. Anything else that could be the problem?

Share this post


Link to post
Share on other sites
Well then it seems that the .cpp file is not being compiled for some reason. Try moving the two statements:

util::list<IMBase*> IMBase::activeList; ///< The list of active objects (with ref_count > 0)
util::list<IMBase*> IMBase::deadList; ///< The list of dead objects (with ref_count == 0)


to your Main.cpp file (make sure it includes the IMBase.h) and rebuild to see if that works.

The only other thing I can think of is that if the util::list is your own user defined data type that represents a list (as in you are not using the stl's list class) then it may be a template problem then. But try the first part of this post first, if it fails still, can we see the util class's definition.

Share this post


Link to post
Share on other sites
Still didn't work.


#ifndef _UTIL_LIST_H_
#define _UTIL_LIST_H_

#include <stddef.h>

namespace util{


/**
* A templated doubly linked list class
*/

template <class T>
class list
{
private:

/**
* A node in a doubly linked list.
*/

struct Node{
T obj; ///< An object of type T
Node* next; ///< A pointer to the next node
Node* prev; ///< A pointer to the previous node

/**
* Constructor
* \param o A const reference to an object of type T
* \param n A pointer to the next node in the list
* \param p A pointer to the previous node in the list
*/

Node(const T& o, Node* n = NULL, Node* p = NULL)
: obj(o), next(n), prev(p)
{ }
};


Node* head; ///< The first linked list element in the list
unsigned int size; ///< The number of elements in the list


public:

/**
* An iterator that is used to step through the linked list
*/

struct iterator{
private:
friend class list<T>; ///< Declare this a friend to list<T> so, list<T> can access its members
Node* current; ///< The current list element being pointed to

public:
/**
* Constructor
* \param n A pointer to an element in the list
*/

iterator(Node* n = NULL)
: current(n)
{ }

/**
* Overloaded operator* (for de-referencing)
* \return A reference of type T to the object element of the
*/

T& operator*() { return current->obj; }

/**
* Overloaded prefix operator++ (but will be used as postfix default function for iterator)
* Moves the iterator forward in the list
*/

void operator++(int j)
{
if( current == NULL )
return;
else
current = current->next;
}

/**
* Overloaded prefix operator-- (but will be used as postfix default function for iterator)
* Moves the iterator backward in the list
*/

void operator--(int j)
{
if( current == NULL )
return;
else
current = current->prev;
}

/**
* Overloaded operator==
* \param i A const reference to an iterator object
* \return true if current pointer is equal to i.current pointer, else false
*/

bool operator==(const iterator& i) { return current == i.current; }

/**
* Overloaded operator!=
* \param i A const reference to an iterator object
* \return true if current pointer is not equal to i.current pointer, else false
*/

bool operator!=(const iterator& i) { return current != i.current; }

/**
* Overloaded assignment operator
* \param i A const refernce to an iterator object
* \return A reference to 'this' iterator object
*/

iterator& operator=(const iterator& i)
{
if( &i != this )
current = i.current;

return *this;
}

}; // iterator


/**
* Constructor
*/

list();

/**
* Copy constructor
* \param l A const reference to a list object
*/

list(const list& l);

/**
* Destructor
*/

~list();

/**
* Delete all elements in the list.
*/

void clear();

/**
* Return an iterator to the first element in the list
* \return An iterator object to the first element in the list.
*/

iterator begin() const;

/**
* Return an iterator to the point after the last element in the list,
* which effectively is a NULL pointer.
*/

iterator end() const;

/**
* Add an element to the back of the list.
* \param o A const reference to an object of type T
*/

void push_back(const T& o);

/**
* Add a list element to the front of the list
* \param o A const reference to an object of type T
*/

void push_front(const T& o);

/**
* Insert an item in the list before the item pointed to by the specified iterator.
* \param i An iterator pointing to the item to insert before
* \param o The item to insert before iterator i
*/

void insertBefore(iterator& i, const T& o);

/**
* Insert an item in the list after the item pointed to by the specified iterator.
* \param i An iterator pointing to the item to insert after
* \param o The item to insert after iterator i
*/

void insertAfter(iterator& i, const T& o);

/**
* Erase the element at this iterator.
* \param i A const reference to an iterator object
*/

void erase(iterator& i);

/**
* Erase a list element.
* \param pos The position of the element to erase
*/

void erase(unsigned int pos);

};

} // namespace util

#endif






Share this post


Link to post
Share on other sites
Quote:
Still didn't work.

Since they're static members, you need to declare them immediately after your class definition in the header file. Try this instead :

class IMBase
{
// class definition ^^
};
util::list<IMBase*> IMBase::activeList; ///< The list of active objects (with ref_count > 0)
util::list<IMBase*> IMBase::deadList; ///< The list of dead objects (with ref_count == 0)

Share this post


Link to post
Share on other sites
Okay, its a problem with the list, and not the IMBase, becuase when I declared a util::list<int> object, I got the same 2 errors, just with an int template.

I just noticed that whenever I compile this, the list header file doesn't show up on the list of dependencies, like all the other header files. It looks like I'm compiling the source, but there's no class definition, even if I add "#include "util\list.h" " to the main source file.

Share this post


Link to post
Share on other sites
Well, now I'm thinking it has to do with the way that I'm compiling the templated files, because I have a dynamic array "array<T>", and I've added that the way it should be, and I get problems with that as well. One different thing is that "array.h" actually comes up in the external dependencies, with all the other header files.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Static member variables don't have to be declared in header file, the source file works fine.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Have you made a default constructor for the list class? The linker errors tell that the constructor hasn't been found.

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!