Copy Constructor, Assignment Operator

Compiler Generated Copy Constructor

Rule

Copy constructor and copy assignment operator is automatically generated if …

  • there is no user defined move constructor

  • there is no user defined move assignment operator

The venerable class point from Classes and Objects is simple

  • Contains only data members

  • Has no user-defined copy constructor ⟶ compiler-generated

  • Does not do resource management in whatever way (see here for why this is dangerous)

  • ⟶ letting the compiler its way is fine

Copy constructor in action (no matter if it is generated or hand-written) …

#include <gtest/gtest.h>
#include "point.h"

TEST(cpp_copy_suite, generated_copy_ctor)
{
    point original{1,2};
    point copy1 = original;  // <--- assignment style, but ctor
    point copy2(original);   // <--- c++03 style
    point copy3{original};   // <--- c++11 style

    ASSERT_EQ(copy1.x(), 1);
    ASSERT_EQ(copy1.y(), 2);
    ASSERT_EQ(copy2.x(), 1);
    ASSERT_EQ(copy2.y(), 2);
    ASSERT_EQ(copy3.x(), 1);
    ASSERT_EQ(copy3.y(), 2);
}

Manually Written Copy Constructor And Assignment Operator

Caution

Careful: if you find yourself writing a copy constructor …

Rule of 5/0

For demonstration purposes: a completely nonsensical copy constructor and assignment operator:

#include <gtest/gtest.h>
#include <string>

class Copyable
{
public:
    Copyable() = default;  // <--- not auto-generated because other ctors are user defined

    Copyable(const std::string& content)
    : content(content) {}

    Copyable(const Copyable& other)            // <--- copy constructor
    : content(other.content + " (copy)") {}

    Copyable& operator=(const Copyable& other) // <--- assignment operator
    {
        content = other.content + " (assignment)";
        return *this;
    }

    std::string content;
};

TEST(manual_copy_suite, copy_ctor)
{
    Copyable original("some object");
    Copyable copy = original;    // <--- copy constructor

    ASSERT_EQ(original.content, "some object");
    ASSERT_EQ(copy.content, "some object (copy)");
}

TEST(manual_copy_suite, assignment_operator)
{
    Copyable original("some object");
    Copyable copy;
    copy = original;             // <--- assignment operator

    ASSERT_EQ(original.content, "some object");
    ASSERT_EQ(copy.content, "some object (assignment)");
}