Home > front end >  Why does my const reference variable, assigned via a getter that returns a const reference, not have
Why does my const reference variable, assigned via a getter that returns a const reference, not have

Time:09-03

I have the following code:

#include <iostream>

class Walltimes 
{
  private:
    double walltime = 0.0;

  public:
    void update_walltime(double delta)
    {
        walltime  = delta;
    }

    double const& get_walltime() const
    {
        return walltime;
    }
};

int main(){
    Walltimes myObj;

    double const& t1 = myObj.get_walltime();  // Time "t1"

    myObj.update_walltime(4.78);              // Update the walltime

    double const& t2 = myObj.get_walltime();  // Time "t2"

    std::cout << "t1: " << t1 << "s\n";
    std::cout << "t2: " << t2 << "s" << std::endl;

    return 0;
}

First of all, the behaviour I want (and the behaviour I thought I would get from running this code) is for t1 to equal 0.0 and t2 be equal to 4.78.

Instead, the output I get is:

t1: 4.78s
t2: 4.78s

When I make t1 and t2 have the type double const (so removing the &) I get the desired output. It also works if I instead remove the reference symbol from my get_walltime() declaration, but not with both references there.

It's worth noting I originally had the references there to avoid copies being made, I just wanted a getter that returns a const reference to the current value of walltime. I realise now that wanting the "current" walltime may require me to deprecate the references(?), as t1 is instead returning what walltime ends up being after it is updated.

Obviously I can fix it with one of the solutions above, but I was wondering if anyone could kindly explain why this current behaviour is happening? Why does t1 know that the walltime will eventually be 4.78? Clearly it's something to do with references and I've tried googling it, but I'm not really satisfied (it probably doesn't help that I'm relatively new to C ). Any help is really appreciated!

CodePudding user response:

Why does t1 know that the walltime will eventually be 4.78?

Because t1 is a reference to the data member walltime for object myObj and so when you wrote myObj.update_walltime(4.78); , you updated the data member walltime of myObj which means the change will be reflected in t1 also as t1 is an alias for walltime.

CodePudding user response:

t1 is a reference to the value contained in the instance; you can't change it through the reference (because the reference is const) but the value it references is mutable. You changed that value before you printed t1. t1, not having any "value" of its own, accurately reported the value found where it references. This is how references work. If you don't want t1 to update, don't make it a reference, so you store a copy by value.

Note that in this case, using references saved you nothing (at least on 64 bit systems). References are typically implemented under the hood with pointers (aside from when the compiler can just avoid a reference at all and just logically use the same place it refers to directly), so returning a 64 bit pointer or a 64 bit double changes nothing, storage-wise, and it's usually slower with the reference (because it has to traverse the pointer each time to find the real value).

  •  Tags:  
  • c
  • Related