initialize static variable in cpp file
Hey guys, here is what I read in CProgramming.com:
You cannot initialize the static class member inside of the class. In fact, if you decide to put your code in a header file, you cannot even initialize the static variable inside of the header file; do it in a .cpp file instead.
Have two questions regarding to this:
1. Kind of curious why it cannot be in header file. As long as the initialization does not happen inside the class should be fine right?
2. Also, can initialization happen in a static member function of the class? If not why?
Thank you so much!
Re: initialize static variable in cpp file
If you initialise the static member in the header file then it would exist as a different copy in every translation unit that included the header file. That is why it must be in the .cpp file. The only exception to this is a static member of a template class, that gets defined in the header file and its up to the linker to sort it out. This has to happen as a template definition in a .cpp file would be inaccessible.
In answer to the second question the only statics that can be initialised within the class are static const primitives. For other class statics they would need be in the .cpp file. The constructors cant initialise statics as statics appear once per class and constructors initialise on a per object basis.
Re: initialize static variable in cpp file
I'm not sure the second question was actually answered. Static members can never be "initialized" inside of a static member function. You can change them (if they aren't const) inside of static member functions but they have to be initialized prior to any static member functions being called. It doesn't make logical sense to allow "initialization" inside of a static member function because there is no guarantee as to which static member function would be called first. Object instances are created via constructors. In that case the constructor runs before any non-static member function so only constructors can initialize non-static members. You see the point? static members are shared by all object instances so there is no function or constructor that could initialize a static member. Therefore it must be done some other way.
Re: initialize static variable in cpp file
Quote:
Originally Posted by
Russco
If you initialise the static member in the header file then it would exist as a different copy in every translation unit that included the header file. That is why it must be in the .cpp file. The only exception to this is a static member of a template class, that gets defined in the header file and its up to the linker to sort it out. This has to happen as a template definition in a .cpp file would be inaccessible.
In answer to the second question the only statics that can be initialised within the class are static const primitives. For other class statics they would need be in the .cpp file. The constructors cant initialise statics as statics appear once per class and constructors initialise on a per object basis.
I see:) Thank you very much!
Re: initialize static variable in cpp file
Quote:
Originally Posted by
kempofighter
I'm not sure the second question was actually answered. Static members can never be "initialized" inside of a static member function. You can change them (if they aren't const) inside of static member functions but they have to be initialized prior to any static member functions being called. It doesn't make logical sense to allow "initialization" inside of a static member function because there is no guarantee as to which static member function would be called first. Object instances are created via constructors. In that case the constructor runs before any non-static member function so only constructors can initialize non-static members. You see the point? static members are shared by all object instances so there is no function or constructor that could initialize a static member. Therefore it must be done some other way.
Thank you for the clear explanation. I learnt a lot:)
Re: initialize static variable in cpp file
Quote:
Originally Posted by
lqakane
You cannot initialize the static class member inside of the class. In fact, if you decide to put your code in a header file, you cannot even initialize the static variable inside of the header file; do it in a .cpp file instead.
This is not entirely accurate. If the static data member is of a
const integral or const enumeration type, its declaration in the class
definition can specify a constant initializer. However, you must
still DEFINE the variable.
Example:
Code:
// in header file
class MyClass
{
static const int Size = 10;
int arr[Size];
};
// in cpp file
const int MyClass::Size; // must still be defined
Re: initialize static variable in cpp file
Quote:
Originally Posted by
Philip Nicoletti
Code:
// in header file
class MyClass
{
static const int Size = 10;
int arr[Size];
};
// in cpp file
const int MyClass::Size; // must still be defined
Actually, this will produce an error:
error LNK2005: "public: static int const MyClass::Size" (?Size@MyClass@@2HB) already defined in MyClass.obj
Also, how did this thread shift to static const member declaration? The OP's question was about static member's INITIALIZATION!
Re: initialize static variable in cpp file
Quote:
Originally Posted by
VladimirF
Actually, this will produce an error:
error LNK2005: "public: static int const MyClass::Size" (?Size@MyClass@@2HB) already defined in MyClass.obj
Not if you ignore the part about putting
Code:
const int MyClass::Size; // must still be defined
inside the cpp file. :D
Re: initialize static variable in cpp file
Quote:
Originally Posted by
VladimirF
Actually, this will produce an error:
error LNK2005: "public: static int const MyClass::Size" (?Size@MyClass@@2HB) already defined in MyClass.obj
Also, how did this thread shift to static const member declaration? The OP's question was about static member's INITIALIZATION!
1) As mentioned in previous post, the definition goes in the CPP file
(as in my comment)
2) My post did give initialization of the static member. It showed
how it does not always have to be in the implementation file.
Re: initialize static variable in cpp file
Just remember:
There can be only one!
A static variable is created once and only once. Russco provided a good explanation of why this is the case.
Re: initialize static variable in cpp file
Quote:
Originally Posted by
VladimirF
Also, how did this thread shift to static const member declaration? The OP's question was about static member's INITIALIZATION!
The OP made an inaccurate statement that static member variables couldn't be initialized in the class declaration. Some of us were simply pointing out that the statement was incorrect and that they can be in limited cases. I think that all of the discussions here were relevant to the OP. You are correct about the linker error though. If the member is initialized in the header than you can't redefine it and reinitialize it in the .cpp as well.
Re: initialize static variable in cpp file
Quote:
Originally Posted by
lqakane
Hey guys, here is what I read in CProgramming.com:
Well what do you expect from CProgramming.com? I recommend these websites for learning a little c++.
http://www.cplusplus.com/
http://www.research.att.com/~bs/homepage.html
http://www.parashift.com/c++-faq-lite/index.html
Re: initialize static variable in cpp file
Quote:
Originally Posted by
PredicateNormative
Not if you ignore the part about putting
Code:
const int MyClass::Size; // must still be defined
inside the cpp file. :D
Actually, I did what you've suggested.
My mistake is - I am using MS extensions to C++ that makes out-of-class definition of static const members "optional".
When these extensions are enabled, you'd get the error I've mentioned.
Sorry for the confusion.
Re: initialize static variable in cpp file
Quote:
Originally Posted by VladimirF
Actually, this will produce an error:
error LNK2005: "public: static int const MyClass::Size" (?Size@MyClass@@2HB) already defined in MyClass.obj
I was not aware of that particular bug in the Visual C++ compiler.
Quote:
Originally Posted by
PredicateNormative
Not if you ignore the part about putting
Code:
const int MyClass::Size; // must still be defined
inside the cpp file. :D
Of course, you can not ignore that as it is required by the standard.
But it looks like that is the only choice for VC++ to get around the bug.
Re: initialize static variable in cpp file
Quote:
Originally Posted by
Philip Nicoletti
Of course, you can not ignore that as it is required by the standard.
:confused:
I'm not saying that you're wrong, perhaps you are right, but I can't find this in the standard, or at least not in the 2005 draft that I have.:ehh:
Re: initialize static variable in cpp file
Quote:
Originally Posted by
MacDaddy C++
There can be only one!
Do you know the HighLander?? ;) ;)
On a more serious note, that is the whole crux of the matter. The "line of code" which defines the static and initializes it (implicitly or explicitly) must be seen by the compiler only once for all of the translation usings that will be linked into the final program.
Typically this is best done by putting the code in a specific .cpp file. And thos post does NOT contract that, nor recommend the following approach (although it is useful in certain very specific cases...
This approach should make immediate sense to anyone who has used preprocessor directives to conditionally "dllExport" / "dllImport"...
SomeFile.h
Code:
class Foo
{
static SomeClass StaticInstance;
};
#ifdef SOME_FILE_CPP_COMPILING
Foo::StaticInstance(params);
#endof
SomeFile.cpp
Code:
#define SOME_FILE_CPP_COMPILING
#include "SomeFile.h"
This can also be accompished using the __FILE__ predefined value.
AGAIN, This is NOT recommended as a general practice. But for cases where the value of the static needs to be "published" (known to users of the header file), it provides a means that is guaranteed to remain "in sync" (A comment in the header file could easily differ from a value in an implementation file.
Re: initialize static variable in cpp file
Quote:
Originally Posted by
PredicateNormative
:confused:
I'm not saying that you're wrong, perhaps you are right, but I can't find this in the standard, or at least not in the 2005 draft that I have.:ehh:
In the 2003 version ... Section 9.4.2 Static data members ... paragraph 4
Quote:
If a static data member is of const integral or const enumeration type,
its declaration in the class definition can specify a constant-initializer
which shall be an integral constant expression (5.19). In that case, the
member can appear in integral constant expressions. The member shall still
be defined in a namespace scope if it is used in the program and the namespace
scope definition shall not contain an initializer.
Re: initialize static variable in cpp file
Quote:
Originally Posted by
Philip Nicoletti
I was not aware of that particular bug in the Visual C++ compiler.
This is NOT a bug, this is an EXTENSION.
If you don’t like it – disable it with a compiler switch.
Following your logic, my car has a bug – it has 10 airbags, while the standard is 2 (or 4, or 6).
Re: initialize static variable in cpp file
Quote:
Originally Posted by
VladimirF
This is NOT a bug, this is an EXTENSION.
If you don’t like it – disable it with a compiler switch.
Following your logic, my car has a bug – it has 10 airbags, while the standard is 2 (or 4, or 6).
????????????????
An incorrect link error is an extension ???
Maybe I don't understand what you did to get the link error.
Do you get the link error with the defintion in the CPP file ? If so,
it is a bug. It is not clear to me what code you used to get an
error. The code that I posted should not get a link error.
Re: initialize static variable in cpp file
Quote:
Originally Posted by
Philip Nicoletti
An incorrect link error is an extension ???
My understanding of this extension is that it treats static const member variable declaration with initialization as definition, making another definition redundant.
Actually, sounds pretty logical to me. Unlike standard initialization with declaration that requires out-of-class definition. If it isn’t defined yet, what do you initialize???
Quote:
Originally Posted by
Philip Nicoletti
Maybe I don't understand what you did to get the link error.
Do you get the link error with the defintion in the CPP file ?
No, you got it right. And I see how it can annoy people who use multiple compilers.
I might have stepped into a wrong forum :)
Re: initialize static variable in cpp file
Quote:
Originally Posted by
Philip Nicoletti
In the 2003 version ... Section 9.4.2 Static data members ... paragraph 4
If a static data member is of const integral or const enumeration type,
its declaration in the class definition can specify a constant-initializer
which shall be an integral constant expression (5.19). In that case, the
member can appear in integral constant expressions. The member shall still
be defined in a namespace scope if it is used in the program and the namespace
scope definition shall not contain an initializer.
I'm not sure I follow what you are suggesting. Actually, I tried an experiment with my compiler because I thought I understood. Take a look at this.
Code:
#ifndef __FOO__
#define __FOO__
class foo
{
public:
static const int defaultValue = 10;
foo();
~foo();
void setValue(int newValue);
int getValue();
private:
int value;
};
#endif
// foo definition
#include "foo.h"
foo::foo()
{
value = foo::defaultValue;
}
foo::~foo()
{
}
void foo::setValue(int newValue)
{
value = newValue;
}
int foo::getValue()
{
return value;
}
#include "foo.h"
int main ()
{
std::cout << "foo::value" << foo::defaultValue << std::endl;
foo f;
std::cout << f.getValue() << std::endl;
f.setValue(5);
std::cout << f.getValue() << std::endl;
return 0;
}
I did not understand the point of the statement in bold. In this case, I still used to defaultValue attribute within the program and within foo's definition without having to define it in the .cpp. Can someone explain what the last sentence in bold means or provide an example that demonstrates its meaning?
I use AdaMulti v4.2.3. it is set to use std c++ without any extensions. Also, I tried defining the defaultValue param in the .cpp file in addition to the declaration and initialization in the header file and received no linker errors. My compiler seems to be happy with or without the definition in the .cpp file so long as it is initialized in the header. That seems inconsistent with the paragraph of the std posted by Philip.
Re: initialize static variable in cpp file
Quote:
Originally Posted by
VladimirF
My understanding of this extension is that it treats static const member variable declaration with initialization as definition, making another definition redundant.
Actually, sounds pretty logical to me. Unlike standard initialization with declaration that requires out-of-class definition. If it isn’t defined yet, what do you initialize???
No, you got it right. And I see how it can annoy people who use multiple compilers.
I might have stepped into a wrong forum :)
VladimirF
How did you disable this extension? I am running into the same problem and would like to disable it.