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).