Search code examples
c++classobjecttemplates

Why can we GET the value of an object within an object, but not SET its value?


In the below code, I have created a very basic template class Pair and its 2 objects - p1 & p2.
I can get the value of data member x of object p2 using cout << p2.getx().getx() << p2.getx().gety();.

Main Question:

If I can GET the value in this way, then why cannot I SET the value of x using (p2.getx()).setx('c'); and (p2.getx()).sety(8.12); ?

Code:

#include<iostream>
using namespace std;

template <typename T, typename V> class Pair {
  T x;
  V y;

  public:
  void setx(T x) {
    this->x = x;
  }
  T getx() {
    return x;
  }
  void sety(V y) {
    this->y = y;
  }
  V gety() {
    return y;
  }
};

int main()
{
  Pair <char,int> p1;  //Declared to put in p2
  p1.setx('b');
  p1.sety(12.23);
  
  Pair <Pair<char,int>, double> p2;
  p2.setx(p1);
  p2.sety(24.36);

  cout<<p2.getx().getx()<<" "<<p2.getx().gety()<<" "<<p2.gety()<<endl;
  (p2.getx()).setx('c');  //Here, p2.getx()!=p1, even though we set p2.x=p1. This is because p2.getx() returns a value/copy of p1 (an instance), not an object (or var).
  (p2.getx()).sety(8.12);
  p2.setx(p1);
  cout<<p2.getx().getx()<<" "<<p2.getx().gety()<<" "<<p2.gety()<<endl;
  return 0;
}

What I think I've understood so far is that p2.getx() returns a copy of p1, and to make p2.getx().setx(value) work, I would have to make it return a reference to p1.
But still what I would like to understand is that if p2.getx().𝒔𝒆𝒕𝒙(𝒗𝒂𝒍𝒖𝒆) doesn't work, how does p2.getx().𝒈𝒆𝒕𝒙() still work?


Solution

  • For your main question, your getx() method returns a copy of x inside p2, if you set value to this copy, will not affect the x inside p2. If you want to change the x inside p2, your getx() method should return a reference like this:

    T& getx() { return x; }
    

    For this question: "But still what I would like to understand is that if p2.getx().𝒔𝒆𝒕𝒙(𝒗𝒂𝒍𝒖𝒆) doesn't work, how does p2.getx().𝒈𝒆𝒕𝒙() still work?"

    p2.getx().𝒔𝒆𝒕𝒙(𝒗𝒂𝒍𝒖𝒆) doesn't work because you didn't set the x inside p2 directly as I explain before. p2.getx().𝒈𝒆𝒕𝒙() works because the first getx() returns a copy of x inside p2, and the second getx() will call the getx() of the copy, so it works.

    Hope I clarify clearly.