Question

Please write a list of tasks that a copy constructor and assignment operator need to do in C++ to keep exception safety, avoid memory leaks etc.

Was it helpful?

Solution

First be sure you really need to support copy. Most of the time it is not the case, and thus disabling both is the way to go.

Sometimes, you'll still need to provide duplication on a class from a polymorphic hierarchy, in that case: disable the assignment operator, write a (protected?) copy constructor, and provide a virtual clone() function.

Otherwise, in the case you are writing a value class, you're back into the land of the Orthogonal Canonical Form of Coplien. If you have a member that can't be trivially copied, you'll need to provide a copy-constructor, a destructor, an assignment-operator and a default constructor. This rule can be refined, see for instance: The Law of The Big Two

I'd also recommend to have a look at C++ FAQ regarding assignment operators, and at the copy-and-swap idiom and at GOTW.

OTHER TIPS

The compiler generated versions work in most situations.

You need to think a bit harder about the problem when your object contains a RAW pointer (an argument for not having RAW pointers). So you have a RAW pointer, the second question is do you own the pointer (is it being deleted by you)? If so then you will need to apply the rule of 4.

Owning more than 1 RAW pointer becomes increasingly hard to do correctly (The increase in complexity is not linear either [but that is observational and I have no real stats to back that statement up]). So if you have more than 1 RAW pointer think about wrapping each in its own class (some form of smart pointer).

Rule of 4: If an object is the owner of a RAW pointer then you need to define the following 4 members to make sure you handle the memory management correctly:

  • Constructor
  • Copy Constructor
  • Assignment Operator
  • Destructor

How you define these will depend on the situations. But things to watch out for:

  • Default Construction: Set pointer to NULL
  • Copy Constructor: Use the Copy and Swap ideum to provide to the "Strong Exception Guarantee"
  • Assignment operator: Check for assignment to self
  • Destructor: Guard against exceptions propagating out of the destructor.

try to read this.

http://www.icu-project.org/docs/papers/cpp_report/the_anatomy_of_the_assignment_operator.html

is a very good analysis of Assignment operator

I have no idea about exception safely here but I go this way. Let's imagine it's a templated array wrapper. Hope it helps :)

Array(const Array& rhs)
    {
        mData = NULL;
        mSize = rhs.size();
        *this = rhs;
    }

    Array& operator=(const Array& rhs)
    {
        if(this == &rhs)
        {
            return *this;
        }

        int len = rhs.size();

        delete[] mData;

        mData = new T[len];

        for(int i = 0; i < len; ++i)
        {
            mData[i] = rhs[i];
        }

        mSize = len;

        return *this;
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top