NirMH
NirMH

Reputation: 4929

Using static class members of the class being defined

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

Answers (4)

David Hammen
David Hammen

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

Sarfaraz Nawaz
Sarfaraz Nawaz

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

iammilind
iammilind

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

Alexander Gessler
Alexander Gessler

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

Related Questions