Often times it's a good idea to have an abstract base class to isolate the interface of the object.

The problem is that copy construction, IMHO, is pretty much broken by default in C++, with copy constructors being generated by default.

So, what are the gotchas when you have an abstract base class and raw pointers in derived classes?

class IAbstract
    ~IAbstract() = 0;

class Derived : public IAbstract
    char *theProblem;

IAbstract *a1 = new Derived();
IAbstract a2 = *a1;//???

And now do you cleanly disable copy construction for the whole hierarchy? Declare copy construction as private in IAbstract?

Are there any rules of three with abstract base classes?

  • 1
    use references instead of pointers :)
    – tp1
    Commented Mar 11, 2012 at 23:34
  • @tp1: or some smart pointer at least. Commented Mar 11, 2012 at 23:56
  • 1
    Sometimes you just have to work with existing code... You can't change everything in an instant.
    – Coder
    Commented Mar 12, 2012 at 0:08
  • Why do you think the default copy constructor is broken? Commented Mar 12, 2012 at 9:08
  • 2
    @Coder: The Google style guide is a pile of junk and absolutely sucks for any C++ development.
    – DeadMG
    Commented Mar 14, 2012 at 13:51

3 Answers 3


Copy construction on an abstract class should be made private in most cases, as well as assignment operator.

Abstract classes are, by definition, made to be a polymorphic type. So you don't know how much memory your instance is using, and so cannot copy or assign it safely. In practice, you risk slicing : https://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c

Polymorphic type, in C++, mustn't be manipulated by value. You manipulate them by reference or by pointer (or any smart pointer).

This is the reason why Java has made object manipulable by reference only, and why C# and D has the separation between classes and structs (the first one being polymorphic and reference type, the second one being non polymorphic and value type).

  • 2
    Things in Java aren't any better. In Java it's painful to copy anything, even when you really, really need to, and very easy to forget to do it. So you end up with nasty bugs where two data structures have a reference to the same value class (e.g. Date), and then one of them changes the Date and the other data structure is now broken. Commented Mar 12, 2012 at 6:00
  • 3
    Meh. It's a non-problem- anybody who knows C++ won't make this mistake. More importantly, there's no reason at all to manipulate polymorphic types by value if you know what you're doing. You're initiating a total knee-jerk reaction over a technically slim possibility. NULL pointers are a bigger problem.
    – DeadMG
    Commented Mar 12, 2012 at 12:34

You could, of course, just make it protected and empty, so that derived classes can choose. However, more generally, your code is forbidden anyway because it's impossible to instantiate IAbstract- because it has a pure virtual function. As such, this is generally a non-issue- your interface classes can't be instantiated and therefore can never be copied, and your more derived classes can ban or keep copying as they wish.

  • And what if there is a Abstract -> Derived1 -> Derived2 hierarchy, and Derived2 is assigned to Derived1? These dark corners of the language still surprise me.
    – Coder
    Commented Mar 12, 2012 at 0:35
  • @Coder: That's usually viewed as PEBKAC. However, more directly, you could always declare a private operator=(const Derived2&) in Derived1.
    – DeadMG
    Commented Mar 12, 2012 at 0:36
  • Ok, maybe this really is not an issue. I just want to make sure the class is safe against abuse.
    – Coder
    Commented Mar 12, 2012 at 0:40
  • 2
    And for that you should get a medal.
    – user28988
    Commented Mar 12, 2012 at 1:11
  • 2
    @Coder: Abuse by whom? The best you can do is make it easy to write correct code. It's pointless to try to defend against programmers who don't know C++. Commented Mar 12, 2012 at 5:58

By making ctor and assignment private (or by declaring them as =delete in C++11) you disable copy.

The point here is WHERE you have to do that. To stay with your code, IAbstract is not an issue. (note that doing what you did, you assign the *a1 IAbstract subobject to a2, loosing any reference to Derived. Value assignment is not polymorphic)

The issue comes with Derived::theproblem. Copying a Derived into another may in fact share the *theproblem data that may be not designed to be shared (there are two instances that may call delete theproblem in their destructor).

If that's the case, it is Derived that must be non-copyable and not assignable. Of course, if you make private the copy in IAbstract, since the default copy for Derived needs it, Derived will also be not copyable. But if you define your own Derived::Derived(const Derived&) without calling IAbtract copy, you can still copy them.

The problem is in Derived, and the solution must stay into Derived: if it must be a dynamic-only object accessed only by pointers or references, it is Derived itself that must have

class Derived
    Derived(const Derived&) = delete;
    Derived& operator=(const Derived&) = delete;

Essentially it is up to the designer of the Derived class (that should know how Derived works and how theproblem is managed) to decide what to do with assignment and copy.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.