Reputation: 141
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
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
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