Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is calling a static member function with . or -> syntax legal? [duplicate]

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?

like image 435
OldPeculier Avatar asked Aug 15 '12 20:08

OldPeculier


People also ask

How do you call a static member function?

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 ::.

What is the correct syntax of accessing a static member of a class in C ++?

Static member functions are called using the class name. Syntax- class_name::function_name( )

What is use of static member function in C++?

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.

What happens if we declare a member function of a class as static?

A static member function can access only the names of static members, enumerators, and nested types of the class in which it is declared.


3 Answers

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.

like image 174
Pete Becker Avatar answered Oct 21 '22 14:10

Pete Becker


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.

like image 31
Rafael Baptista Avatar answered Oct 21 '22 14:10

Rafael Baptista


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 ]

like image 7
Flexo Avatar answered Oct 21 '22 15:10

Flexo