-2

I have a question about the object life time and assigning values to member variables vs calling member variables via an encapsulation like a getter. In my code I want to update a member variable m_a in the CLASS2::Update() method. I then call this method via a member variable class2, defined in CLASS1. In CLASS1::UpdateMemberVariable(), I directly use class2 to call the CLASS2::Update() method and in CLASS1::UpdateEncapsulation() I use encapsulation to call the CLASS2::Update() method. In the former case class2.getA() returns 5 after m_a is assigned the value 5. However, in the latter case getClass2().getA() returns 0. It seems that getClass2().getA() constructs the class2 object again, since it did not safe any changes to m_a. My question is why this is the case? class2 should remain untill the a_encapsulate (defined in main) is destroyed, even when using a getter functions right?

Thanks in advance!

#include <iostream>

class CLASS2
{
    public:
        void Update();
        int getA(){return m_a;};
    private:
        int m_a{0};
};

void CLASS2::Update()
{
     std::cout << "Update a" << std::endl;
     m_a = 5;
} 

class CLASS1
{
    public:
        void UpdateMemberVariable();
        void UpdateEncapsulation();
        CLASS2 getClass2(){return class2;};
    private:
        CLASS2 class2;
};


void CLASS1::UpdateMemberVariable()
{
    
    //member variable
    std::cout << "\n" <<std::endl;
    std::cout << "MEMBER VARIABLE" << std::endl;
    std::cout << class2.getA() << std::endl; // prints 0
    class2.Update(); //sets m_a to 5
    std::cout << class2.getA() << std::endl; //prints 5
}

void CLASS1::UpdateEncapsulation()
{
    std::cout << "\n" <<std::endl;
    std::cout << "ENCAPSULATION" << std::endl;
    //Encaptulation
    std::cout << getClass2().getA() << std::endl; // prints 0
    getClass2().Update(); // sets m_a to 5
    std::cout << getClass2().getA() << std::endl; //prints 0 (Why does it print 0 here? -> m_a has been set to 5?)
}


int main()
{
    CLASS1 a_memberVariable;
    a_memberVariable.UpdateMemberVariable();

    CLASS1 a_encapsulate;
    a_encapsulate.UpdateEncapsulation();
    return 0;
}
  • 2
    `getClass2()` returns a copy of the member – 463035818_is_not_an_ai Sep 26 '22 at 08:38
  • 1
    Instead of `CLASS2 getClass2()`, try `CLASS2& getClass2()` Then invest in [some good C++ books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282) and read about *references*. – Some programmer dude Sep 26 '22 at 08:40
  • Thanks! So I should probably define member variable class2 as a pointer instead of a normal value? Or should I define getClass2() to return a reference to class2? – Yorick de Jong Sep 26 '22 at 08:40
  • 1
    depends what you want or need. Though, returning a non-const reference is not encapsulation. Rather than granting direct access to the members, methods should model behavior of the class – 463035818_is_not_an_ai Sep 26 '22 at 08:44

1 Answers1

0

getClass returns a copy of the member. Your code with minor modifications to illustrate what is happening, turning the temporary copies into more explicit copies:

void CLASS1::UpdateEncapsulation()
{
    std::cout << "\n" <<std::endl;
    std::cout << "ENCAPSULATION" << std::endl;
    auto copy1 = getClass2();
    std::cout << copy1.getA() << std::endl;       // prints copy1.m_a
    auto copy2 = getClass();
    copy2.Update();                               // sets copy2.m_a to 5 
    auto copy3 = getCass();
    std::cout << copy3.getA() << std::endl;       // prints copy3.m_a
} 
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185