Home > Net >  why should I pass by reference return if my function use static member
why should I pass by reference return if my function use static member

Time:10-04

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;
}
  •  Tags:  
  • c
  • Related