Копировать конструкторы в C ++ - PullRequest
0 голосов
/ 10 февраля 2012

У меня есть эти классы:

первый:

 class C 
 {
     public:
     C(const C& c):_s(c._s){}
     c():_s(""){}

     string _s;
 }

второй:

class C2: public C
{
    public:
    C2(const C2 & c2):_i(c2.i){}
    C2():_i(0){}

    int _i;
}

основной:

int main()
{
    C2 c2;
    C2._s="hello";
    c2._i=42;
    C2 c3(c2);
    cout<<c3._s<<" "<<c3._i<<endl;
}

и выход42. Мой вопрос: почему вывод 42?Базовый конструктор всегда вызывается перед производными конструкторами, поэтому эта строка:

C2 c3(c2);

должна вызывать конструктор копирования C и должна копировать "hello", что означает, что вывод должен быть hello.Что мне здесь не хватает?

Ответы [ 4 ]

4 голосов
/ 10 февраля 2012

Причина

C2(const C2 & c2):_i(c2.i){}

не инициализирует _s значениями, хранящимися в c2, потому что конструктор по умолчанию (без параметров) базового класса вызывается, если не указано иное, и поэтому _s также инициализируется конструктором по умолчанию, а не конструктором копирования.

В вашем случае C2::(const C2&) вызывает C::C(), а это string::string().

Вы должны явно вызвать правильный базовый конструктор:

C2(const C2 & c2) :
  C( c2 ),
  _i(c2.i)
{
}
1 голос
/ 10 февраля 2012

Вызывается конструктор копирования для объекта. По умолчанию (компилятор сгенерированный) конструктор копирования вызывает конструктор копирования для каждого члена, затем конструктор копирования для каждого базового класса. Конструктор копирования написанное вами делает именно то, что вы написали, не больше, не меньше. Большинство время, определяемый пользователем конструктор копирования должен начинаться с копирования построение его баз:

C2::C2( C2 const& other )
    : C( other )
    , _i( other._i )
{
}

Однако есть исключения, и бывают случаи, когда вы не хотите скопировать базу.

1 голос
/ 10 февраля 2012

Помимо опечатки (строка s-> строка _s), конструктор копирования производного класса должен вызвать конструктор для базового класса

, т. Е.

C2(const C2 & c2):C(c2), _i(c2.i){} 

BTW -вопрос был бы проще с менее похожими именами для типов в качестве переменных

0 голосов
/ 10 февраля 2012

Да, базовый класс вызывается перед производным классом, КОТОРОЙ вызывается конструктор базового класса, однако это соответствует спецификации производного класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...