►Автоматический конструктор копирования...215

Копирующий конструктор так же важен, как и конструктор по умолчанию. Важен настолько, что С++ считает невозможным существование класса без копирующего конструктора. Если вы не создадите свою версию такого конструктора, С++ создаст её за вас. ( Это несколько отличается от конструктора по умолчанию, который создаётся только в том случае, если в вашем классе не определено вообще никаких конструкторов. )

_________________

215 стр. Глава 18. Копирующий конструктор

«Копирующий конструктор, создаваемый С++, выполняет поэлементное копирование всех членов-данных. Ранее копирующий конструктор, создаваемый С++, выполнял побитовое копирование. Отличие между этими методами заключается в том, что при поэлементном копировании для каждого члена класса вызываются соответствующие копирующие конструкторы ( если они существуют ), тогда как при побитовом копировании конструкторы не вызывались. Разницу в результатах можно увидеть, выполнив приведённый пример.»

[Диск]

    /* DefaultCopyConstructor — демонстрация вызова */

    /*                    конструктором копирования по */

    /*                     умолчанию конструкторов */

    /*                     копирования членов */

    #include <cstdio>

    #include <cstdlib>

    #include <iostream>

    #include <strings.h>

    using namespace std ;

    const int MAXNAMESIZE = 40 ;

    class Student

    {

      public :

        Student( char *pName = "no name" )

        {

            strcpy( name , pName ) ;

            cout << "Конструируем " << name << endl ;

        }

        Student( Student& s )

        {

            strcpy( name , "Копия " ) ;

            strcat( name , s.name ) ;

            cout << "Сконструирована " << name << endl ;

        }

        ~Student( )

        {

            cout << "Деструкция " << name << endl ;

        }

      protected :

        char name[ MAXNAMESIZE ] ;

    } ;

    class Tutor

    {

      public :

        /* Вызов конструктора копирования Student */

        Tutor( Student& s ) : student( s )

        {

            cout << "Конструирование объекта Tutor" << endl ;

            id = 0 ;

        }

      protected :

_________________

216 стр. Часть 3. Введение в классы

        Student student ;

        int id ;

    } ;

    void fn( Tutor tutor )

    {

        cout << "В функции fn( )" << endl ;

    }

    int main( int argcs , char* pArgs[ ] )

    {

        setlocale ( LC_ALL , ".1251" ) ; /* печать кириллицы */

        Student Chester( "Chester" ) ;

        Tutor tutor( Chester ) ;

        cout << "Вызов fn ( )" << endl ;

        fn( tutor ) ;

        cout << "Возврат из fn( )" << endl ;

        /* Пауза для того, чтобы посмотреть на результат работы программы */

        system( "PAUSE" ) ; return 0 ;

    }

Запуск этой программы приведёт к выводу таких сообщений:

    Конструируем Chester

    Сконструирована Копия Chester

    Конструирование объекта Tutor

    Вызов fn( )

    Сконструирована Копия Копия Chester

    В функции fn( )

    Деструкция Копия Копия Chester

    Возврат из fn( )

    Press any key to continue . . .

    Деструкция Копия Chester

    Деструкция Chester

Конструирование объекта Chester приводит к вызову конструктора Student, который выводит первое сообщение. Конструктор объекта tutor вызывает копирующий конструктор Student для генерации собственного члена student, и приводит к выводу следующих двух строк.

Затем программа передаёт копию объекта Tutor в функцию fn( ). Поскольку класс Tutor не определяет копирующий конструктор, программа вызывает конструктор копирования по умолчанию.

Конструктор копирования по умолчанию Tutor вызывает конструкторы копирования для членов-данных. Копирующий конструктор для int просто копирует значение, но конструктор копирования Student генерирует вывод на экран строки Сконструирована Копия Копия Chester. Деструктор копии вызывается как часть возврата из функции fn( ).