Concepts / Copying Objects in C++

Copying Objects in C++

A concrete type allows direct manipulation of its objects.

  • Programming

Predicting What a Copy Does

When you write a program, one important design question is how the program will work with the objects of a type. Suppose you have an object a and you create a second object b from it. Are a and b the same object, or are there now two separate objects? If you change b later, does a change too? Hold these questions in mind as you read, because the answers depend on whether the type is concrete.

What do you think happens?

Suppose a is an object with value 5, you create b as a copy of a, and then you set b.value to 10. What is a.value now?

  • 5

  • 10

  • It depends on the compiler

Reveal answer
Answer:

5

A copy produces a second, independent object. Changing b does not change a. The code example later in this article shows this with real C++ syntax.

What a Concrete Type Allows

Definition

A concrete type is a type that allows direct manipulation of its objects. The advantages of concrete types describe what becomes possible once a type is concrete: its objects can be placed in particular locations in memory, they can be referred to directly, they can be initialized fully and immediately, and they can be copied.

The four advantages are easier to remember as one group under the single idea of a concrete type. Each advantage answers a different version of the same question: what could a program do with a concrete object that it could not do if it could only reach that object through a pointer or a reference? The rest of this article takes the four advantages in turn and then returns to that question.

Tracing a Copy Step by Step

The clearest way to understand copying is to follow the state of two objects before and after the copy. The example below defines a small type B with one data member, creates an object a, copies it into b, and then changes only b. The code is written for illustration and is not taken from the source.

Code walkthrough
class B {
public:
    int value;
};

int main() {
    B a;
    a.value = 5;
    B b = a;
    b.value = 10;
    return 0;
}
  1. 1
    Line 1 declares the concrete type B, so objects of type B can be manipulated directly by name.
  2. 2
    Declaring B a creates an object a and gives it a place to live.
  3. 3
    Setting a.value to 5 gives a the state we will compare later.
  4. 4
    The declaration B b = a creates a second, separate object b from the existing object a.
  5. 5
    Setting b.value to 10 changes b alone. Because b is a separate object, a keeps its own value of 5.
  • class B defines a concrete type with one data member called value
  • B a; creates an object a of type B on the stack
  • a.value = 5; sets the state of a
  • B b = a; makes a new object b that starts as a copy of a
  • b.value = 10; changes only b
Output
The program prints nothing. After the copy, a.value is 5 and b.value is 10.
Before
B a;
a.value = 5;

a holds value 5

After
B b = a;
b.value = 10;

a still holds value 5 and b holds value 10

avalue = 5avalue = 5bvalue = 10
After B b = a, are a and b the same object, and does changing b also change a? Before the copy there is one object. After the copy there are two independent objects, and changing b leaves a unchanged.

Read the diagram from left to right. Before the change, a holds 5. After the copy and the update, a still holds 5 while b, the new object, holds 10. The changed node is only b, which is exactly what it means for the copy to be an independent second object.

Placing Concrete Objects in Memory

The first advantage of a concrete type is placement. Objects of a concrete type can be placed in several kinds of storage: they can be placed on the stack, they can be placed in statically allocated memory, and they can be placed inside other objects. Because a concrete type supports all three placements, the programmer is not forced to store every object in one fixed kind of location.

Stackplacement optionStatically allocatedmemoryplacement optionInside another objectplacement option
Which storage locations can a concrete object occupy? The source lists three: the stack, statically allocated memory, and inside other objects.

The practical meaning is flexibility. A concrete object can be a standalone local value, a shared object with static storage, or a component that lives inside a larger object. The important point is that the object itself, not only a route to it, can be stored in these places.

Direct Reference Versus Reaching Through a Pointer

The second advantage is direct reference. The source is careful to distinguish this from referring to objects only through pointers or references. A pointer or a reference is one way to reach an object, but it is an indirect route. A concrete type makes it possible to refer to the object itself, so the indirect route is not the only option.

Object itselfdirect referencePointer or referenceindirect routeObjectthe data is reacheddirectlyObjectthe data is reached throughthe routerefers toleads to
How does a variable that holds the object itself differ from a variable that reaches the object through a pointer or reference?

In the left column, the variable names the object directly. In the right column, the variable is only a route, and the program must go through it to reach the data. The source's point is that concrete types let the program work with the object itself when that is what the design needs.

Complete Initialization at Creation

The third advantage is that concrete types allow objects to be initialized immediately and completely. The source gives constructors as the example mechanism. A constructor is the part of an object's creation that sets it up, so with a concrete type the object reaches a usable, fully set-up state as part of its creation, not in a separate, later step.

Read the process as a progression. The object starts as something being created, the constructor takes part in setting it up, and the result is an object that is initialized immediately and completely. The benefit comes from the word immediately: the object is never left in an incomplete state while the program waits for a later setup step.

Copying an Existing Object

The fourth advantage is that concrete types enable object copying. Copying means producing another object from an existing one. A program can make a new object from an existing object of a concrete type rather than being restricted to using only the original. The copy example earlier in this article, in which b is made from a, is this advantage in action.

Copying is therefore one of the reasons concrete types are useful. Having both a original object and an independent copy gives the program a second object it can change without touching the first.

When Working with Concrete Objects Directly Helps

Return to the question from the start: what could a program do with a concrete object that it could not do if it could only reach that object through a pointer or a reference? The four advantages suggest several situations. A program can choose where an object is placed, refer to the object itself, create it fully in one step, and make an independent copy of it. When a design needs any of these, working with the concrete object directly is the natural choice.

Mistakes Beginners Make When Copying

  • Common mistake

    Assuming a copy is another name for the same object

    What it looks like

    B b = a; b.value = 10; then expecting a.value to also be 10

    Why it fails

    The copy is a separate object, so a change to b is stored in b only.

    Do this instead

    Read the copy as producing a new, independent object, and check each object's own state after a change.

  • Common mistake

    Treating a pointer or reference as the object itself

    What it looks like

    Thinking a variable that reaches an object through a pointer holds the object's data directly

    Why it fails

    A pointer or reference is an indirect route to the object. The source distinguishes this from direct reference to a concrete object.

    Do this instead

    Ask whether the variable holds the object or a route to it, and reason about each case separately.

  • Common mistake

    Forgetting that the source lists placement in the stack, static memory, and inside other objects as separate options

Practice Tracing a Copy

EASY

Suppose a concrete object a has value 3. You write B b = a; and then set a.value to 7. What is b.value? Explain your answer in terms of the two independent objects.

Hints
  • Ask whether b is a separate object or another name for a.
  • Check which object's value was changed by the last assignment.

Summary of Concrete Type Advantages

  1. 1
    A concrete type allows direct manipulation of its objects.
  2. 2
    Its four advantages are placement, direct reference, complete initialization, and copying.
  3. 3
    Objects of a concrete type can be placed on the stack, in statically allocated memory, and inside other objects.
  4. 4
    Copying produces a separate second object, so changing the copy does not change the original.

At a glance

  • A concrete type allows direct manipulation of its objects.
  • Placement, direct reference, complete initialization, and copying are the four advantages of concrete types.
  • Concrete objects can be placed on the stack, in statically allocated memory, and inside other objects.
  • Copying creates an independent second object, so changes to the copy do not affect the original.

Related concepts

More concepts starting with C