2 разных типа вызова конструктора из конструктора копирования

Рассмотрим пример кода ниже:

#include <iostream>

using namespace std;

class core
{
   public:
      core(const core& obj)
      {
         cout << "core copy ctor called\n";
      }
      core()
      {
         cout << "core default ctor called\n";
      }
};

class sample : public core
{
   public:
      sample()
      {
         cout << "sample default ctor called\n";
      }
#if 0
      sample(const sample& obj)
      {
         cout << "sample copy ctor called\n";
      }
#endif
};

int main()
{
   sample s1;
   sample s2 = s1; //Line1
   return 0;
}

Тип 1: конструктор копирования не объявлен явно для образца класса

(Тип1 показан в приведенном выше коде. Затем компилятор неявно генерирует конструктор копии образца класса). Когда выполняется оператор Line1, сначала вызывается конструктор копирования class core, а затем вызывается конструктор копирования class sample.

Тип 2: конструктор копирования определен явно для примера класса

Когда выполняется оператор Line1, сначала вызывается конструктор по умолчанию class core, а затем вызывается конструктор копирования class sample.

Вопрос:

Почему такая разница в поведении конструктора копирования, как указано в Type1 и Type2?


person nitin_cherian    schedule 30.12.2011    source источник


Ответы (1)


Потому что конструктор копирования, который вы явно определяете для sample, не требует вызова конструктора копирования core. Вам придется написать : core(obj), если вы хотите, чтобы это произошло.

Иными словами, когда вы пишете явный конструктор копирования, вы берете на себя ответственность за создание копии sample, включая его подобъект core. Написав это так, как вы это сделали, вы решили не инициализировать подобъект core с помощью obj. Поскольку вы не сказали, как вы делаете его инициализацию, компилятор вместо этого просто использует конструктор по умолчанию core, отсюда и поведение во втором случае, который вы описываете.

Напротив, в первом случае сгенерированный компилятором конструктор копирования по умолчанию для sample действительно запрашивает инициализацию подобъекта core с помощью конструктора копирования core, отсюда и наблюдаемое поведение.

person Stuart Golodetz    schedule 30.12.2011
comment
Я это понимаю. Но какова мотивация этой разницы в поведении. Почему Type1 и Type2 не могут вести себя одинаково? - person nitin_cherian; 30.12.2011
comment
Рассмотрим случай, когда вы можете не захотеть, чтобы подобъект core инициализировался с помощью конструктора копирования core — это дает вам способ избежать этого. - person Stuart Golodetz; 30.12.2011
comment
Идеально!. Я понял. +1 за ответ и разъяснение :) - person nitin_cherian; 30.12.2011
comment
Суть в том, что если вы хотите заменить конструктор копирования по умолчанию таким образом, чтобы сохранить поведение, вам нужно сделать именно то, что он делает, включая правильную инициализацию подобъекта базового класса. Можно утверждать, что гибкость, которую вы получаете от возможности инициализировать подобъект другим способом, иногда больше, чем вам нужно/хотите, но так работает язык :) - person Stuart Golodetz; 30.12.2011