Patrick
Patrick

Reputation: 141

What if a static member is not initialized and the member type is class itself?

A class is defined like this:

class Singleton {
public:
    static Singleton instance_;

private:
    Singleton() {
        cout << "constructor\n";
    }
};

In a function:

Singleton instance = Singleton::instance_;

Code can be compiled and no error was thrown. If I use it like this:

Singleton &instance = Singleton::instance_;

A link error was thrown. I wonder why the first case can be compiled correctly? And I know the constructor function was not called. What's the object state of instance in the first case? Does the first case make any sense?

Upvotes: 2

Views: 62

Answers (2)

Serge Ballesta
Serge Ballesta

Reputation: 148890

Static members are only declared when the class is defined. They must be defined outside of the class definition. In your case, you should write:

class Singleton {

public:
    static Singleton instance_; // declare the static member

private:
    Singleton() {
        cout << "constructor\n";
    }
};

Singleton Singleton::instance_; // defines the static member

This is mainly used when you need non trivial construction, but if you forget to define the static member, it simple does not exists and you get either a link error or undefined behaviour at run time.

Upvotes: 0

user743382
user743382

Reputation:

Both forms are an error in your code, but in both cases compilers/linkers are allowed to silently ignore the error, they're not required to detect it.

Singleton instance = Singleton::instance_; uses the implicitly generated copy constructor. It copies all 0 non-static data members from Singleton::instance_, and is therefore likely to be optimised away entirely. Therefore, the fact that you're using Singleton::instance_ without a definition is likely to go unnoticed.

Singleton &instance = Singleton::instance_; binds to Singleton::instance_ and requires its address to be known. Therefore, it is more likely to result in an error if Singleton::instance_ is not defined.

The way you can provide a definition of Singleton::instance_ is

Singleton Singleton::instance_;

at file scope.

Upvotes: 2

Related Questions