using static variables

J

jois.de.vivre

Hi, I'm having some linker issues when using static variables in a
class.

class TestClass
{
public:

TestClass()
{
Count++;
}

private:
static int Count;
};

int main(int argc, char *argv[])
{
TestClass T;
return EXIT_SUCCESS;
}


The above gives me an undefined reference (to TestClass::Count) error
during linking. How can I get this to work without having to put my
function definitions in a cpp file?

Thanks
 
M

mlimber

Hi, I'm having some linker issues when using static variables in a
class.

class TestClass
{
public:

TestClass()
{
Count++;
}

private:
static int Count;
};

int main(int argc, char *argv[])
{
TestClass T;
return EXIT_SUCCESS;
}


The above gives me an undefined reference (to TestClass::Count) error
during linking. How can I get this to work without having to put my
function definitions in a cpp file?

With static data members, you must declare them inside the class (as
you have done) and then define/initialize them somewhere outside the
class (as you have neglected to do). For instance, you could write:

int TestClass::Count = 0;

before or after the definition of main().

Cheers! --M
 
J

jois.de.vivre

With static data members, you must declare them inside the class (as
you have done) and then define/initialize them somewhere outside the
class (as you have neglected to do). For instance, you could write:

int TestClass::Count = 0;

before or after the definition of main().

What if I had the class definition in a separate file, say testclass.h,
which included the following:

//-- begin testclass.h
#ifndef TESTCLASSH
#define TESTCLASSH

class TestClass
{
private:
static int Count;

public:

TestClass()
{
Count++;
}
};
int TestClass::Count = 0;

#endif
// --- end testclass.h


and main() in a separate file, say main.cpp:

//-- begin main.cpp
#include <testclass.h>

int main(int argc, char *argv[])
{
TestClass t;
return EXIT_SUCCESS;
}
// --- end main.cpp

I get a multiple definitions of TestClass::Count error, but I want the
initialization of Count to take place in testclass.h, is this possible?
 
V

Victor Bazarov

What if I had the class definition in a separate file, say
testclass.h, which included the following:

//-- begin testclass.h
#ifndef TESTCLASSH
#define TESTCLASSH

class TestClass
{
private:
static int Count;

public:

TestClass()
{
Count++;
}
};
int TestClass::Count = 0;

That's bad. It's an object definition in a header. Never put object
definitions in your headers. It has to go into _one_of_ your translation
units. Which one is usually immaterial.
[..]

I get a multiple definitions of TestClass::Count error, but I want the
initialization of Count to take place in testclass.h, is this
possible?

No, not possible. No initialisation happens in "testclass.h". It's just
another piece of text included in (all or some) of your translation units.
Whatever you have in your "testclass.h" will be _replicated_ in all C++
source files where you write '#include "testclass.h"' (or some such). It
means the headers should only contain _declarations_. Class definitions
are essentially _declarations_. Object definitions don't belong to
headers. Period.

V
 
M

mlimber

With static data members, you must declare them inside the class (as
you have done) and then define/initialize them somewhere outside the
class (as you have neglected to do). For instance, you could write:

int TestClass::Count = 0;

before or after the definition of main().

What if I had the class definition in a separate file, say testclass.h,
which included the following:

//-- begin testclass.h
#ifndef TESTCLASSH
#define TESTCLASSH

class TestClass
{
private:
static int Count;

public:

TestClass()
{
Count++;
}
};
int TestClass::Count = 0;

#endif
// --- end testclass.h


and main() in a separate file, say main.cpp:

//-- begin main.cpp
#include <testclass.h>

int main(int argc, char *argv[])
{
TestClass t;
return EXIT_SUCCESS;
}
// --- end main.cpp

I get a multiple definitions of TestClass::Count error, but I want the
initialization of Count to take place in testclass.h, is this possible?

You shouldn't get that error here. I suspect you're including the same
header file in a different .cpp file.

In any case, there is no way to do what you want. The static member
must be defined in only one translation unit, and the only way to
control that if you're including the header in multiple .cpp files is
to take it out of the header. The simplest solution is to create a
testclass.cpp file that only #includes your header and defines and
initializes the data. Then no users are responsible for defining it,
but they will need to link in your extra .cpp file.

Cheers! --M
 
J

jois.de.vivre

Victor said:
What if I had the class definition in a separate file, say
testclass.h, which included the following:

//-- begin testclass.h
#ifndef TESTCLASSH
#define TESTCLASSH

class TestClass
{
private:
static int Count;

public:

TestClass()
{
Count++;
}
};
int TestClass::Count = 0;

That's bad. It's an object definition in a header. Never put object
definitions in your headers. It has to go into _one_of_ your translation
units. Which one is usually immaterial.
[..]

I get a multiple definitions of TestClass::Count error, but I want the
initialization of Count to take place in testclass.h, is this
possible?

No, not possible. No initialisation happens in "testclass.h". It's just
another piece of text included in (all or some) of your translation units.
Whatever you have in your "testclass.h" will be _replicated_ in all C++
source files where you write '#include "testclass.h"' (or some such). It
means the headers should only contain _declarations_. Class definitions
are essentially _declarations_. Object definitions don't belong to
headers. Period.

V


What's the best way of initializing Count then? It just seems inelegant
to have a cpp file devoted entirely to initalizing one static variable.
 
V

Victor Bazarov

[..]
What's the best way of initializing Count then? It just seems
inelegant to have a cpp file devoted entirely to initalizing one
static variable.

There is no "best way". There is only _one_ way; the question can
only be "where". But the problem is (for some) that *any* cpp file
would do.

Just pick one, and forget we ever had this conversation.

V
 
D

David Harmon

On 12 Sep 2006 11:13:04 -0700 in comp.lang.c++,
(e-mail address removed) wrote,
I get a multiple definitions of TestClass::Count error, but I want the
initialization of Count to take place in testclass.h, is this possible?

There might be some trick to make it possible, but generally: no.
Put the definition in one and only one .cpp file.

This issue is covered in Marshall Cline's C++ FAQ. See the topic
"[10.10] Why are classes with static data members getting linker
errors?" You can get the FAQ at:
http://www.parashift.com/c++-faq-lite/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,778
Messages
2,569,605
Members
45,237
Latest member
AvivMNS

Latest Threads

Top