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.
unique_ptr
. – Investigatorshared_ptr
to pass around to several other classes. – Daryldarylep
. – Daryldaryle