why the result of this code gives the same value of _x
and I'm using static instance inside getInstance()
it retrieve the same object.
class A{
public:
A(){}
A getInstance();
void print(){
_x=_x 1;
std::cout<<"the value of x is : " <<_x<<std::endl;
}
int _x = 0;
};
A A::getInstance(){
static A _instance;
return _instance;
}
int main() {
A a;
a.getInstance().print(); //the value of x is : 1
a.getInstance().print(); //the value of x is : 1
return 0;
}
when I use &A
as a type of getInstance()
the result is
the value of x is : 1
the value of x is : 2
can anyone explain me why ?
CodePudding user response:
Your A A::getInstance(){
returns a copy of the static instance: static A _instance;
. This copy has a _x
equal to the Static A::_x
which is initialised to 0 and is not modified.
This ultimately means that .print
is called on the returned temporary object instead of upon A itself so each time the print function is invoked this temporaty object has its _x
incremented and is then destroyed leaving the static A unchanged.
When you return by reference from A& A::getInstance
the .print()
acts upon the static A
variable twice incrementing it from 0 to 1 then to 2 in the second print. You would get the same behaviour if you returned by pointer : A* A::getInstance()
.
CodePudding user response:
I modified your example a bit so you can better see what happens. The "problem" (it works exactly as expected) is that if you don't return a reference a copy of A will be returned. Run the code and you can see for yourself.
Note I made the instance getters static so you don't need to create an instance of A first (makes the output more clear). And I made the constructor private so you only can use the singleton creation methods.
Output of the example :
2 times get_Instance
A::A(), _x = 0
A::getInstance(), _instance.x_ = 0
A::A(const A&), _x = 0
the value of x is : 1
A::getInstance(), _instance.x_ = 0
A::A(const A&), _x = 0
the value of x is : 1
2 times get_InstanceRef
A::A(), _x = 0
A::getInstanceRef(), _instance.x_ = 0
the value of x is : 1
A::getInstanceRef(), _instance.x_ = 1
the value of x is : 2
And the example itself:
#include <iostream>
class A
{
public:
static A getInstance();
static A& getInstanceRef();
void print() {
_x = _x 1;
std::cout << "the value of x is : " << _x << std::endl;
}
private:
A() { std::cout << "A::A(), _x = " << _x << " \n"; }
A(const A&) { std::cout << "A::A(const A&), _x = " << 0 << "\n" ; }
int _x = 0;
};
A A::getInstance()
{
static A _instance;
std::cout << "A::getInstance(), _instance.x_ = " << _instance._x << "\n";
return _instance;
}
A& A::getInstanceRef()
{
static A _instance;
std::cout << "A::getInstanceRef(), _instance.x_ = " << _instance._x << "\n";
return _instance;
}
int main()
{
std::cout << "2 times get_Instance\n";
auto a1 = A::getInstance();
a1.print();
auto a2 = A::getInstance();
a2.print();
std::cout << "\n2 times get_InstanceRef\n";
auto& a3 = A::getInstanceRef();
a3.print();
auto& a4 = A::getInstanceRef();
a4.print();
return 0;
}