Possible Duplicate:
C++ Static member method call on class instance
Today I discovered that something I had long (and I mean long—like, for twenty years), thought illegal in C++ is actually legal. Namely, calling a static member function as if it belonged to an individual object. For example:
struct Foo
{
static void bar() { cout << "Whatever."; }
};
void caller()
{
Foo foo;
foo.bar(); // Legal -- what?
}
I normally see static member functions being called strictly with "scope resolution syntax," thus:
Foo::bar();
This makes sense, because a static member function is not associated with any particular instance of the class, and therefore we wouldn't expect a particular instance to be syntactically "attached" to the function call.
Yet I discovered today that GCC 4.2, GCC 4.7.1, and Clang 3.1 (as a random sampling of compilers) accept the former syntax, as well as:
Foo* foo = new Foo;
foo->bar();
In my particular case, the legality of this expression led to a runtime error, which convinced me that the peculiarity of this syntax is of more than academic interest—it has practical consequences.
Why does C++ allow static member functions to be called as if they were direct members of individual objects—that is, by using the . or -> syntax attached to an object instance?
Static Function Members By declaring a function member as static, you make it independent of any particular object of the class. A static member function can be called even if no objects of the class exist and the static functions are accessed using only the class name and the scope resolution operator ::.
Static member functions are called using the class name. Syntax- class_name::function_name( )
The static member functions are special functions used to access the static data members or other static member functions. A member function is defined using the static keyword. A static member function shares the single copy of the member function to any number of the class' objects.
A static member function can access only the names of static members, enumerators, and nested types of the class in which it is declared.
In The Design and Evolution of C++ at page 288, Bjarne Stroustrup mentions that in the days before static member functions, programmers used hacks like ((X*)0)->f()
to call member functions that didn't need an object. My guess is that when static member functions were added to the language, access through ->
was allowed so that programmers with code like that could change f
to static
without having to hunt down and change every use of it.
Presumably so you can call it in places where you may not know the class type of something but the compiler does.
Say I had a bunch of classes that each has a static member that returned the class name:
class Foo
{
static const char* ClassName() { return "Foo"; }
};
class Bar
{
static const char* ClassName() { return "Bar"; }
};
Then all over my code I could do things like:
Foo foo;
printf( "This is a %s\n", foo.ClassName() );
Without having to worry about knowing the class of my objects all the time. This would be very convenient when writing templates for example.
It's like this because the standard says that's how it works. n3290 § 9.4 states:
A static member s of class X may be referred to using the qualified-id expression
X::s;
it is not necessary to use the class member access syntax (5.2.5) to refer to a static member. A static member may be referred to using the class member access syntax, in which case the object expression is evaluated. [ Example:struct process { static void reschedule(); }; process& g(); void f() { process::reschedule(); // OK: no object necessary g().reschedule(); // g() is called }
end example ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With