Reputation: 1771
I'm writing a class using singleton mode. The code is as below:
A.h
#include <iostream>
class A {
public:
static A get_instance();
static A* get_instance_ptr();
void init(int i);
void print_data(void);
private:
static A* instance_ptr;
int data;
};
A* A::instance_ptr = NULL;
A* A::get_instance_ptr()
{
if (NULL == instance_ptr) {
instance_ptr = new A();
}
return instance_ptr;
}
A A::get_instance()
{
return *get_instance_ptr();
}
void A::init(int i)
{
data = i;
std::cout << "In A::init, data = " << data << std::endl;
}
void A::print_data(void)
{
std::cout << "In A::print_data, data = " << data << std::endl;
}
main.cpp:
#include <iostream>
#include "A.h"
int main(int argc, _TCHAR* argv[])
{
A::get_instance().init(42);
A::get_instance().print_data();
return 0;
}
The principle is to initialize data
in A::init()
and print it in A::print_data
. But the output is:
In A::init, data = 42
In A::print_data, data = 0
It seems the data
initialization didn't work. But if I change the initialization in main
to:
A::get_instance_ptr()->init(42);
The output is as expected:
In A::init, data = 42
In A::print_data, data = 42
So the question is, why the member initialization failed in the first try?
Upvotes: 0
Views: 141
Reputation: 437336
Because the return type of get_instance
is A
instead of the correct A&
and therefore a copy of your "singleton" is returned each time you call it. The init
call operates on a copy of your original object, then print_data
operates on a different copy. When all is said and done, main
has managed to create three copies of the singleton.
Singletons that can be copied are not really singletons. You should do the bare minimum to prevent copies (declaring private ctors and assignment operator and not defining them).
Upvotes: 2