Вот код вопроса, когда я пишу это:
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
, b
, c
, d
и e
неинициализированными, а
код не отвечает за копирование назначения, и
выражение new Bla(other.p)
требует, чтобы у Bla
был конструктор, принимающий std::shared_ptr<Bla>
, что крайне маловероятно.
С std::shared_ptr
это должен быть код C ++ 11, чтобы быть формально правильным в отношении языка.Тем не менее, я считаю, что это просто код, который использует то, что доступно с вашим компилятором.Поэтому я считаю, что соответствующим стандартом C ++ является C ++ 98 с техническими исправлениями поправки C ++ 03.
Вы можете легко использовать встроенную (сгенерированную) инициализацию копирования, даже в C++ 98, например,
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;
};
Обратите внимание, что этот код правильно инициализируется в конструкторе по умолчанию, отвечает за назначение копирования (для этого используется swap idiom ) и нетребуется специальный конструктор Bla
с поддержкой смарт-указателей, но вместо этого просто используется обычный конструктор копирования Bla
для копирования.