CS 70

What About References?

  • Sherlock speaking

    As a detective, I know a thing or two about aliases.

  • RHS Cow speaking

    Wonderful! You should be able to help us out, then!

Allocation Phase

In our model, no extra space is allocated for the reference, since it's another name for an existing object (whose space has already been allocated).

(Of course we know that references often do require some space to be allocated in practice, but our model abstracts this implementation detail away.)

  • Sherlock speaking

    That seems logical. No matter how many aliases I take on, I'm still just one Sherlock.

Initialization Phase

Nothing happens to the value, regardless of whether it's a reference to a primitive or an instance of a class. The only thing that happens is that the reference name becomes useable.

  • Sherlock speaking

    Again, this matches my detective experience. When I take on a new alias, I do not change who, or what, I am. I merely begin to respond to a new name.

  • RHS Cow speaking

    That's… surprisingly deep.

Use Phase

Any attempts to use the reference are the same as attempts to use the thing it refers to.

  • Sherlock speaking

    I pride myself in my ability to respond naturally to all of my aliases!

Destruction Phase

Nothing happens to the value, regardless of whether it's a reference to a primitive or an instance of a class. The only thing that happens is that the name becomes unusable.

  • Sherlock speaking

    It would indeed be a tragedy if shaking off an alias caused any long-term change to my being.

Deallocation Phase

In our model, no space is deallocated for the reference, since it's another name for an existing object.

(In practice, there may be some behind-the-scenes inner-workings memory associated with the reference that is deallocated along with the rest of the stack frame, but we don't need to worry about that.)

The space for the object will be deallocated, when its time comes, according to the object-lifetime rules of the object itself, which doesn't necessarily happen at the same time as the reference's destruction/deallocation!

  • Sherlock speaking

    Aliases come and go, but I remain. Still, I am acutely aware that deallocation comes to us all eventually.

  • RHS Cow speaking

    That… went a little dark.

  • LHS Cow speaking

    Anyway, thank you for the expert insights!

An Easy Way To Remember

Our lifecycle model really reflects what's happening with the boxes in our memory model. We don't draw any boxes for references, so the allocation, initialization, destruction, and deallocation phases don't do anything to the contents of the boxes!

Initialization and destruction just involve writing or crossing out a name.

Practice Problem

Suppose that, once again, we have Cow functions with print statements in them,

Cow::Cow() {
    cout << "Cow default constructor called!" << endl;
}

Cow::Cow(const Cow& other) {
    cout << "Cow copy constructor called!" << endl;
}

Cow::operator=(const Cow& other) {
    cout << "Cow assignment operator called!" << endl;
}

Cow::~Cow() {
    cout << "Cow destructor called!" << endl;
}

and that we write the following program that uses our functions:

1| int main() {
2|     Cow bessie{};
3|     Cow mabel = bessie;
4|     Cow& daisy = mabel;
5|     bessie = daisy;
6| }

How many times will the Cow copy-constructor message be printed?

How many times will the Cow destructor be called at the end of the function?

(When logged in, completion status appears here.)