Q:

Call default copy constructor from within overloaded copy constructor

I need to write a copy constructor that deep copies the contents of a std::shared_ptr. However, there are a bunch of variable int a, b, c, d, e; also defined in the class. Is there a way to generate the default copy constructor code (or call the default copy constructor) inside my new overloaded one.
Here is a code snippet with a comment that hopefully clarifies the issue.
class Foo {
public:
     Foo() {}
     Foo(Foo const & other);
     ...
private:
     int a, b, c, d, e;
     std::shared_ptr<Bla> p;
};

Foo::Foo(Foo const & other) {
    p.reset(new Bla(*other.p));

    // Can I avoid having to write the default copy constructor code below
    a = other.a;
    b = other.b;
    c = other.c;
    d = other.d;
    e = other.e;
}

A:

I always think that questions like this should have at least one answer quote from the standard for future readers, so here it is.
§12.8.4 of the standard states that:

If the class definition does not explicitly declare a copy constructor, one is declared implicitly.

This implies that when a class definition does explicitly declare a copy constructor, one is not declared implicitly. So if you declare one explicitly, the implicit one does not exist, so you can't call it.

A:

Here’s the question code as I’m writing this:
class Foo {
public:
     Foo() {}
     Foo(Foo const & other);
     ...
private:
     int a, b, c, d, e;
     std::shared_ptr<Bla> p;
};

Foo::Foo(Foo const & other) {
    p.reset(new Bla(other.p));

    // Can I avoid having to write the default copy constructor code below
    a = other.a;
    b = other.b;
    c = other.c;
    d = other.d;
    e = other.e;
}

The above code is most likely wrong, because

the default constructor leaves a, b, c, d and e uninitialized, and
the code does not take charge of assignment copying, and
the expression new Bla(other.p) requires that Bla has a constructor taking a std::shared_ptr<Bla>, which is extremely unlikely.

With std::shared_ptr this would have to be C++11 code in order to be formally correct language-wise. However, I believe that it’s just code that uses what’s available with your compiler. And so I believe that the relevant C++ standard is C++98, with the technical corrections of the C++03 amendment.
You can easily leverage the built-in (generated) copy initialization, even in C++98, e.g.
namespace detail {
    struct AutoClonedBla {
        std::shared_ptr<Bla> p;

        AutoClonedBla( Bla* pNew ): p( pNew ) {}

        AutoClonedBla( AutoClonedBla const& other )
            : p( new Bla( *other.p ) )
        {}

        void swap( AutoClonedBla& other )
        {
            using std::swap;
            swap( p, other.p );
        }

        AutoClonedBla& operator=( AutoClonedBla other )
        {
            other.swap( *this );
            return *this;
        }
    };
}

class Foo {
public:
     Foo(): a(), b(), c(), d(), e(), autoP( new Bla ) {}
     // Copy constructor generated by compiler, OK.

private:
     int                      a, b, c, d, e;
     detail::AutoClonedBla    autoP;
};

Note that this code does initialize correctly in the default constructor, does take charge of copy assignment (employing the swap idiom for that), and does not require a special smart-pointer-aware Bla constructor, but instead just uses the ordinary Bla copy constructor to copy.

A:

It would be easier to write a variation on shared_ptr that has deep copying built into it. That way, you don't have to write a copy constructor for your main class; just for this special deep_copy_shared_ptr type. Your deep_copy_shared_ptr would have a copy constructor, and it would store a shared_ptr itself. It could even have an implicit conversion to shared_ptr, to make it a bit easier to use.

