C++ calling a static method

Viewed 6317

Let's say you have the following class:

struct Foo {        
    static void print(std::string x) { std::cout << x << std::endl; }       
};

What is the difference between calling print like

Foo foo; //Or a pointer...
foo.print("Hello world");

and

Foo::print("Hello world");

?

3 Answers

There's no difference at the point of calling. It's six of one and half a dozen of another.

Foo::print("Hello world"); is more idiomatic; a convention has grown up where this signals to the reader that print is likely to be a static function. To that end, using foo.print("Hello world"); in your particular case is idiosyncratic, and therefore confusing. So avoid this way, particularly if there's an overhead in introducing an unnecessary instance foo.

Note that the notation using the scope resolution operator can also be used if you want to reach a specific override of a print within another method in a complex class hierarchy! Hence my use of likely above.

There's the obvious difference in that the first version has to construct and destruct a Foo.

Then there's the obvious similarity in that both versions do the same thing when the function call is executed (construct a string, print, etc).

The less obvious difference, is in the evaluation of the two expressions. You see, even though foo is not required for the call, it's still evaluated as part of the expression:

[class.static]/1

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

In your case that doesn't mean anything. But in certain contexts, it can prevent your program from compiling at all. For instance, if foo was instead a reference parameter in a constexpr function.

There's no difference in your example. Keep in mind the static variables are share among all the instances of your class. So you can access them through scope operator or via member selection:

class A{
    public:
        A(){count++;}
        ~A(){count--;}

        static int count;
};

int A::count = 0;

int main(){
    A aObj, bObj, cObj;

    std::cout << "number of A instances: " << A::count << std::endl;
    std::cout << "number of A instances: " << aObj.count << std::endl;

    return 0;
}
Related