Concepts / Object Lifetime and Destructors

Object Lifetime and Destructors

Keeping track of which object owns the resource is what prevents leaks and double releases.

  • Programming

Why Every Transfer Needs a Decision

Every time a program passes a container to a function, returns one, or stores one in another variable, it has to decide what happens to the data inside. The container might be duplicated, so that two independent objects hold the same elements. Or its contents might be handed over to a new owner, so that the original no longer holds them. These two choices are the subject of copy and move semantics.

Read the next few sections with one question in mind: after this operation finishes, how many objects are responsible for the data, and what state is each one in? Almost every rule about copying, moving, and destroying objects is an answer to that question.

Copying a Container

Copying a container creates a second container that holds the same values as the first. Afterward the two containers are separate objects. Changing an element in one does not change the element in the other. Copying is the operation that produces this independent second object, and it is the default way to make a duplicate when no other choice has been made explicitly.

The important point is that both containers remain usable and independent. Each one is responsible for its own elements. Because the elements must be duplicated, a copy can take more time and memory than the original took to create, especially when the container is large.

original containerelements 1, 2, 3original storage1, 2, 3copy containerelements 1, 2, 3copy storage1, 2, 3ownsowns
After a copy, do the original and the new container share storage, or does each hold its own storage with the same values?

Tracing a Copy Step by Step

Worked example

Copying a three-element container

A container named scores holds the elements 90, 75, and 88. The program creates a second container named backup as a copy of scores, then changes the first element of backup to 60. What does scores hold afterward?

  1. 1
    Start with the original

    scores owns its elements, and they are 90, 75, and 88.

  2. 2
    Make the copy

    backup is created as a second container holding the same values, 90, 75, and 88. It is a separate object, and it is responsible for its own elements.

  3. 3
    Change one container

    Setting the first element of backup to 60 changes only backup's element. The change happens in the copy's own storage.

  4. 4
    Check the original

    scores still holds 90, 75, and 88, because the two containers never shared their elements.

Result

scores still holds 90, 75, and 88. backup holds 60, 75, and 88. The copy and the original are independent.

Moving a Container

Moving a container transfers its contents to a new container instead of duplicating them. The destination takes over the data, and the source is left in a valid but unspecified state. A move is useful when the source is no longer needed, because the program avoids building a second copy of the elements. This is why a move can be cheaper than a copy: no elements need to be duplicated, because the existing data changes hands.

In C++ code, the move is requested by casting the source to an rvalue reference with std::move. This tells the language that the source may give up its contents.

sourceowns buffer holding 1, 2, 3sourcevalid, unspecifieddestinationnot yet holding elementsdestinationowns buffer holding 1, 2, 3
Where does the buffer holding the elements live before and after a move, and what state is the source left in?

What do you think happens?

After a move, what do you think the source container holds?

  • Nothing, because its contents were removed

  • The same elements it held before the move

  • A valid but unspecified state, so code should not depend on its contents

Reveal answer
Answer:

A valid but unspecified state, so code should not depend on its contents

The source is left valid but unspecified. It is not guaranteed to be empty, and it is not guaranteed to keep its elements, so a program should not rely on what the source holds after the move.

Who Owns the Resource

A container usually owns a resource, such as a block of memory that holds its elements. Copy and move operations decide what happens to that resource. A copy must give the new object its own resource, so that two objects never release the same memory. A move hands the existing resource to the new object and leaves the source without it, so that only one object is responsible for it at any time.

Keeping track of which object owns the resource is what prevents leaks and double releases. A leak happens when a resource is never released. A double release happens when two objects both try to release the same resource. Copies avoid the second problem by creating new resources, and moves avoid it by transferring the single existing resource.

The Essential Operations Working Together

Copy and move behavior is controlled by a small group of special member functions. Together they describe how an object is created from another object, how an existing object is assigned from another, and how an object is cleaned up. The essential operations are the copy constructor, the copy assignment operator, the move constructor, the move assignment operator, and the destructor.

The constructors create a new object, while the assignment operators replace the value of one that already exists. A copy version takes a read-only reference to its source, and a move version takes a reference that allows the source to be emptied. The destructor is the step that releases what the object owns. Seeing these operations as a set makes it clear that copying and moving are two forms of the same job, producing a new value from an existing one, and that destruction is what ends the object's ownership.

copy constructorcreates a new object froman existing onecopy assignmentreplaces an existing valuewith a copymove constructorcreates a new object bytaking contentsowned resourceblock holding the elementsmove assignmentreplaces a value by takingcontentsdestructorreleases what the objectownsnew resourcenew resourcetransfers resourcetransfers resourcereleases
How do the copy and move operations, and the destructor, each relate to the resource a class manages?

Suppressing Copy or Move

Sometimes a class should not be copied or moved at all. A handle that represents a unique external resource, or an object whose identity matters, may be wrong to duplicate. Suppressing an operation means stating that the operation is not available, so that code which tries to use it fails to compile instead of silently producing an incorrect result. Choosing to allow or suppress an operation is a design decision about what the class means.

Suppressed operationWhat is blockedWhat remains availableWhy a designer might choose it
Copy operationsCreating an independent duplicate and copy assignmentMove operations, when the class provides themThe object represents a unique resource that should not be duplicated, but its ownership can be handed to a new owner
Move operationsTransferring contents to a new object or valueCopy operations, when the class provides themMoving would give up the object's contents in a way that breaks its meaning, while duplicating it is still acceptable
Both copy and moveDuplicating and transferring the objectCreating the object and cleaning it up with the destructorThe object's identity matters, so it should only be created and then used where it lives

Which operations remain available when a class suppresses copying or moving

Mistakes Learners Make with Copies and Moves

  • Common mistake

    Assuming a moved-from source still holds its original elements

    What it looks like

    After moving scores into another container, the code reads scores and expects 90, 75, and 88.

    Why it fails

    The source is left in a valid but unspecified state, so its contents are not something the program can rely on after the move.

    Do this instead

    Use the destination after a move, and only reassign or destroy the source.

  • Common mistake

    Copying a large container when the source is no longer needed

    What it looks like

    A function returns a large container built inside it, and the caller duplicates it again instead of handing it over.

    Why it fails

    A copy must duplicate every element, which can take more time and memory than the original took to create.

    Do this instead

    When the source will not be used again, a move hands the existing resource to the new owner instead of building a second copy.

  • Common mistake

    Treating copy and move as the same operation

    Why it fails

    A copy leaves two objects that each own their own resource, while a move leaves only one object responsible for the resource.

Practice Tracing Ownership

MEDIUM

A container named readings owns the elements 4, 8, and 15. A program first copies readings into a container named archive, then moves readings into a container named latest. For each of the three containers (readings, archive, latest), say whether it owns a resource holding elements after the moves, and say what its state is. Explain your answer in terms of copies creating new resources and moves transferring existing ones.

Hints
  • Start by drawing who owns a resource after the copy, before you consider the move.
  • After the move, the source is valid but unspecified, so do not claim it still holds 4, 8, and 15.
  • Count how many objects own a resource holding the elements after each step.

Key Takeaways

  • A copy produces a second, independent container holding the same values, and each container owns its own resource.
  • A move transfers the existing resource to a new owner and leaves the source valid but unspecified, which makes it cheaper than a copy when the source is no longer needed.
  • The copy constructor, copy assignment, move constructor, move assignment, and destructor together control how objects are created, replaced, and released.
  • A class can suppress copy or move operations to state that they are not available, so misuse fails at compile time when the object's meaning forbids duplication or transfer.

Related concepts

More concepts starting with O