c++ static vars in a class

Started by
9 comments, last by pavel989 15 years, 1 month ago
hey guys, I have a class with a buncha static variables. compiling my program i get a buncha linker errors that follow this pattern: 1>window.obj : error LNK2001: unresolved external symbol "private: static struct tagPOINT * Window::lpPoint" (?lpPoint@Window@@0PAUtagPOINT@@A) i think im gettin them bc i have another header file, which is holding a global object of that class. it links to the header of the class header. and thus, all the files that link to my object header, are screwing up the class, in a sense. Is that possible? i really dunno what to do.
Advertisement
When you declare a static variable in a class, you need to add a definition of the variable somewhere; generally in the same file that you implement the rest of the class, though this isn't necessary. For example if you have:
class MyClass {  public:    static int i;};

In one source file at namespace scope (not inside a function or class definition) put:
int MyClass::i;
If you have a class with a static member variable, in atleast one .cpp file (ie where the rest of the class definition is) you need to actually define the variable at the global scope (or inside whatever namespace your "Window" class exists in).

something like:
in window.cpp
struct tagPOINT * Window::lpPoint = NULL;


:( SiCrane is too fast.
tried that, but dint work.

ima check maybe i did something wrong. i felt that it worked like an extern where i have to declare it.

does it matter that i haven't implemented namespaces
actually i think i did bad linking:




class file
|
object header-----------|
______________________________|
| | |
file1 file2 file3

so technically its being called like 3 times or w/e. Could that be the problem?
uhm, that was a failed attempt. looked fine in the text enter field. dammit
Quote:Original post by pavel989
so technically its being called like 3 times or w/e. Could that be the problem?

No, if you have proper ifdef guards (your error message indicates you have not such problem).


Instead of:
// Window.hstruct tagPOINT;class Window {  static tagPOINT* lpPoint;};// Window.cpptagPOINT* Window::lpPoint = NULL;

you could try with:
// Window.hstruct tagPOINT;class Window {  static tagPOINT*& lpPoint() {     static tagPOINT* point = NULL;     return point;   };};// Window.cpp empty!

You need to replace lpPoint with lpPoint() everywhere, but it might solve your problem.
well the thing is, lppoint is one of many things. so idk if itd make sense to do it for all those things
No, it does not make sense. It is a bad solution.
SiCrane and KulSeran have both answered the question.

Adding a static member variable in a class body only provides a declaration for that variable. You still need to provide one, and only one, definition. Not extern. Not a pseudo-singleton. Just a definition in a source file.

You shouldn't define a global variable in a header file anyway, since it usually leads to multiple definitions.

Incidentally, C++ does not have tag names, so there is no point in doing "struct tagFoo", which is a C-ism.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Quote:Original post by pavel989
tried that, but dint work.

ima check maybe i did something wrong. i felt that it worked like an extern where i have to declare it.

does it matter that i haven't implemented namespaces


No. As static data members have class scope then ensuring a valid class definition is sufficient.

Static data members must be declared at class scope and defined at file scope (as stated previously).

One quick point... static data members are subject to class-member access rules. As you've declared lpPoint to be a private static member only class-methods and friends have access to it.

Anyway... because you're dealing with a pointer to a structure I'd personally ensure that it was a well defined pointer type prior to its usage in any data definition. For example:

// somewhere.htypedef struct tagPOINT{...} TAGPOINT, *P_TAGPOINT;//window.h#include "somewhere.h"class Window{   private:      static P_TAGPOINT lpPoint;};//window.cpp#include "window.h"P_TAGPOINT Window::lpPoint;



The issue you would have would be assigning a valid address to this pointer when it's used as a private static member of Window. You would need to provide a public static interface to do this. Within Window add:

   public:      static void SetTagPoint(const P_TAGPOINT pPt)      {          lpPoint = pPt;      }


Cheers,

Timkin

This topic is closed to new replies.

Advertisement