Reputation: 4929
Using static class members in a class is a common practice. consider the following definition:
foo.h
class foo
{
public:
virtual ~foo();
protected:
foo();
static foo ms_oFooStaticObject;
}
foo.cpp
foo foo::ms_oFooStaticObject;
foo::foo(){}
foo::~foo(){}
void main()
{
int i;
}
while compiling the above code there is no compiler error, and you can simply run in step mode and observe the static c-tor being executed.
how can this be? is this a compiler bug?
I am using visual studio 2005 (Professional Edition) with SP1 (SP.050727-7600)
Upvotes: 0
Views: 121
Reputation: 33116
@user797308: I assume you would have no problem if someone declared and defined a global variable named ms_oFooStaticObject. In other words, rather than defining foo foo::ms_oFooStaticObject;
define foo ms_oFooStaticObject;
(This would require the constructor was public, of course).
Plain old vanilla global variables are declared via extern <type> <global_name>;
and defined using <type> <global_name>;
(possibly with some initial value).
Those static members in a class are really just global variables with the class name prepended in front of their names. The class definition is declaring them. Think of the declaration of ms_oFooStaticObject inside of class foo as being analogous to extern foo ms_oFooStaticObject;
. How about the definition of the variable? That's what that foo foo::ms_oFooStaticObject;
statement is doing.
The comparison with globals is quite apt. There's a lot of baggage associated with globals. It is a good idea to think of the static members of a class as having the same kinds of problems as do globals in general.
Edit
Nawaz's response triggered a thought. user797308's problem might be that foo::ms_oFooStaticObject
itself is protected, so how can it be defined at file scope? The answer is that because the language requires those static data members to be defined at file scope, the language of course has to allow such definitions, even for static members that have non-public visibility.
Upvotes: 1
Reputation: 361352
Let me guess. I think you're wondering because the foo
is made protected
, and therefore, you think the following line must give error, as it tries to invoke the non-public constructor from outside.
foo foo::ms_oFooStaticObject; //definition lies outside the class
Well, that is not true. ms_oFooStaticObject
is NOT a global object, though at first it seems it is, seeing its definition which is outside the class.
The fact is that ms_oFooStaticObject
is still a member of the class, even though its definition is outside the class. And like any member, it can access not only protected
members, it can access even private
ones:
class A
{
A() { cout << "constructed" << endl; } //private constructor
static A a;
};
A A::a; //okay - member has access to private constructor!
A b; //error - non-member doesn't has access to private constructtor
Compile and see the error message along with line number: http://www.ideone.com/qocH0
By the way, your main()
is non-standard, it should be one of these:
int main();
int main(int argc, char *argv[]);
Upvotes: 0
Reputation: 69988
Constructor foo::foo()
is executed because of static
variable definition you did in foo.cpp file:
foo foo::ms_oFooStaticObject;
You are invoking the object of class foo
.
Upvotes: 0
Reputation: 46607
It's not a compiler bug - constructing static instances of the class being defined does not trigger recursive construction (as a non-static member of type foo
would do), so it is perfectly fine.
At the point of ms_oFooStaticObject
's definition (in foo.cpp), foo
is a complete type and its constructor, though protected
, is accessible to ms_oFooStaticObject
.
Upvotes: 4