9

Inspired by this question.

Usually the reason to make copy-constructor and assignment operator private is to make the class non-copyable so that objects can only be created and destroyed, but not copied - most of the times it is because copying them would make no sense. In such cases the copy constructor and the assignment operator are both made private and not implemented - if the class is not copyable then noone should copy.

Is there a case when copy constructor and assignment operator need to be private and have meaningful implementation at the same time?

Community
  • 1
  • 1
sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • read up on C++0x's deleted functions, which are syntactic sugar for this kind of thing by using `= delete` instead of jumping through hoops. – rubenvb Jul 25 '11 at 11:22
  • 1
    How is this not a dupe of the other question? The other doesn't specify *only* private constructors with implementations, but at least one answer (http://stackoverflow.com/questions/6811037/whats-the-use-of-the-private-copy-constructor-in-c/6811507#6811507) involves that. – Steve Jessop Jul 25 '11 at 11:39
  • @Steve Jessop: The problem is the number one reason to have them private is to prevent copying completely and then they are left unimplemented and that's what most people (me too) think of when they are asked about this. Since I'm particularly interested in "private+implemented" scenario I had to ask this question and put specific emphasis. – sharptooth Jul 25 '11 at 11:42
  • @sharptooth: true, almost all of the answers over there are reasons a class could be uncopyable. – Steve Jessop Jul 25 '11 at 11:44
  • @Steve Jessop: Btw that answer is good. – sharptooth Jul 25 '11 at 11:44

3 Answers3

8

My guess is that this can be useful for a class that is holding a list of itself - then it can copy the instances internally. This is really only useful for a class that is both the item and the container:

class MyItems
{
private:
    /* Copy ctor and =operator */
    List list;
public:
    void AddItems(MyItems* items)
    {
        MyItems* added = new MyItems(items);
        list.Add(added);
    }
};

Another thought is to allow cloning in circumstance controlled by the class. This might be useful when copying can make sense, but only on specific conditions or permissions:

class MyClass
{
private:
    /* Copy ctor and =operator */
public:
    MyClass* clone()
    {
        if (canClone)
        {
            MyClass* cloned = new MyClass(this);
            return cloned;
        }
        else
        {
            return NULL;
        }
    }
};
Eli Iser
  • 2,788
  • 1
  • 19
  • 29
  • 1
    Why would you want to forbid clients from making copies in the first example? – R. Martinho Fernandes Jul 25 '11 at 11:28
  • 1
    @Martinho: The `List` object might not take ownership with `List::add`. Hence, keeping clients from creating copies in the first example saves you from having to worry who owns the `MyItem` instances in the `list` member. – Frerich Raabe Jul 25 '11 at 11:42
8

There are two cases that come to mind immediately:

  1. friends:

    Say that, as part of your design, you have two highly coupled classes where one needs to be able to copy the other (say, as in a factory model or some such), but you don't want to let the whole world be able to copy it.

  2. wrappers:

    Say you want to be able to conditionally clone some element, depending on some internal behavior (e.g., depending on some class-stateful condition) - the cleanest way, from a language perspective - is still to separate the copying into its own function. This would allow for good separation of concerns.

Nate
  • 12,499
  • 5
  • 45
  • 60
7
  1. We make copy constructor and operator = unimplemented so that even a friend cannot have any access to it. If you implement, it means you want a friend to have access. This is a design decision.
  2. You want to do explicit cloning; i.e. allow copying but also make its code "dirty" looking (something like C++ style casting operations, which shows dirt in your code)

e.g.

class A {
  A(const A& obj) { ... }
  A& operator = (const A& obj) { ... }
public:
  A& clone(const A& obj)
  {
    *this = obj;
    return *this;
  }
};

We have put this wrapper clone() to allow the user for cloning, however it also displays explicitly what exactly he/she is doing.

iammilind
  • 68,093
  • 33
  • 169
  • 336