C++ assign const reference to instance variable (memory issues?)

4.1k views Asked by At

I always thought that references were functionally the same as pointers, they just have a much friendlier syntax, and some other minor differences ( references cannot be assigned to null, they cannot be reassigned).

But today I saw this code and I do not understand why it is correct:

There is simple struct, Color3B. We create one on the stack like this:

Color3B color(255,0,0);

There is another class, one of its instance variables is of Color3B type.

class Node{

private:
    Color3B _color;
public:
    void setColor(const Color3B& color){
        _color = color;
    }
};

Usage:

void someFunction(){
    Color3B color(255,0,0);   
    _someNode->setColor(color);    
}

I think color is destroyed when it is out of scope: when someFunction ends. But setColor gets a memory address of something created on the stack, and stores it. But there are no issues, when I access Node's _color, it is always there and has a correct value.

What am I missing here?

3

There are 3 answers

0
Bathsheba On

_color = color; takes a value copy of color so it doesn't matter that color eventually goes out of scope.

You'd have issues if the member variable _color was itself a reference.

0
Lectem On
void someFunction(){
    Color3B color(255,0,0);    // (1)
    _someNode->setColor(color);// (2)  
}                              // (5)


void setColor(const Color3B& color){ // (2)(3)
    _color = color;                  // (4)
}                                    

Let's see what happens here :

  1. create an object named color
  2. give it by reference to setColor
  3. the parameter color is now a reference (alias) of color
  4. copy the value of color into _color (assignment) because _color is not a reference
  5. color is destroyed
0
rozina On

The error that you think should happen would happen if _color was a reference.

class Node{

private:
    const Color3B& _color;
public:
    void setColor(const Color3B& color){
        _color = color;
    }
};

This code would produce the error you expect. Now you actually would save the address of the color on stack into Node and that would be destroyed at the end of someFunction(). However you do not do that. Your Node has its own Color3B object, not a reference to it. So the code _color = color actually performs a copy from the color in someFunction() to the color in Node object. Now even if the original color gets destroyed, the one in Node lives on.

If you wrote setColor() with a pointer, the equivalent to your code would be:

void setColor(const Color3B* color){
    _color = *color;
}

Because a reference is not an address of a variable but an alias. So color in the above code (if it is a reference) represents the value of it, not the address. To get the address you would have to write &color.