3

I was doing my homework assignment and encountered a question which required us to return a value by reference. I got the question correct, but I'm not sure why. Can anyone care to explain me how this member function of a struct actually works. (or you could even direct me to a detailed resource). The code for the member function is:

double& SafePtrToDouble::Dereference(){
  if((*this).d!=nullptr){ 
    return *((*this).d);
  }
  else{ throw std::logic_error("Error");}
}

Please tell if this description is a little vague. Thank you!

Esh200111
  • 71
  • 1
  • 8
  • 1
    Its' the `&` in your function return type, read up on what it does https://www.edureka.co/blog/call-by-reference-in-cpp – IndieGameDev Nov 19 '20 at 10:55
  • 2
    What part of it are you unsure about? Also note that `(*this).d` could be written as `this->d` – super Nov 19 '20 at 10:58
  • 1
    You solved the problem without knowing how the code works? I wish I was that lucky :( Anyway, here is a list of [good C++ books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) or you could add some details to explain what exactly you don't understand, so we can focus our answer on the right topic. – Lukas-T Nov 19 '20 at 11:01
  • I'm confused in the part that ```*((*this).d)``` returns a double value (I haven't specified it), but the function returns a reference to a double. Aren't those 2 types different? – Esh200111 Nov 19 '20 at 11:01

2 Answers2

2

When returning a value by reference problems might arrise when a the memory of the returned referenced object is freed. This might happen for example because the object has automatic lifetime and the variable goes out of scope and is freed. Since the value is returned by reference this would result in a dangling reference. In your case the lifetime of the referenced object does not have auto lifetime. Therefore the returned refernce stays valid after the function call and no dangling refernce triggers undefined behaviour.

Example of a typical error:

double& SafePtrToDouble::Dereference(){
    double retval= 10;
    return retval; //the address of retval is returned
} // the variable retval is freed => reference is dangling now
David Feurle
  • 2,687
  • 22
  • 38
  • 3
    `when a the returned value is allocated on the stack` it is better to talk about lifetime, storage duration, and ownership. Stack and heap are a detail of how the standard is implemented. Furthermore, the value itself could be allocated on the heap, but then owned by an object that has a storage duration that ends when the function is left and due to that would delete the referenced value that is allocated in the heap, which would also result in a dangling reference. – t.niese Nov 19 '20 at 12:33
  • @t.niese you are completely right, I thought I just give an example of the most common error. Of course it would be correct to talk about the lifetime of the object here. – David Feurle Nov 19 '20 at 13:46
2

double is a distinct type to double &, but they are related. You need a double object somewhere to initialise a double & value. Reference types are one of the two kinds of types that aren't objects.

In this case, the expression *((*this).d) identifies the object that the reference binds to. You can think of a reference variable as a new name for an existing object. An object with dynamic storage duration ("on the heap") doesn't have a name when it is created, so a reference could be the "only" name it has.

Caleth
  • 52,200
  • 2
  • 44
  • 75