►Перегрузка конструктора...200

Поскольку в этой главе проводятся параллели между конструктором и обычными функциями-членами, я позволю себе ещё одну параллель: конструкторы можно перегружать.

«Словосочетание "перегруженная функция" означает, что определено несколько функций с одинаковым именем, но разными типами аргументов. Если вы немного подзабыли этот термин, освежите память, обратившись к главе 6, "Создание функций".»

[Помни!]

С++ выбирает вызываемый конструктор, исходя из аргументов, передаваемых при объявлении объекта. Например, класс Student может одновременно иметь три конструктора, что продемонстрировано в следующем примере:

    /* OverloadConstructor — несколько способов */

    /*                          создать объект путём */

    /*                    перегрузки конструктора */

    #include <cstdio>

    #include <cstdlib>

    #include <iostream>

    #include <strings.h>

    using namespace std ;

    const int MAXNAMESIZE = 40 ;

    class Student

    {

      public :

        Student( )

_________________

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

        {

            cout << "Конструктор Student( )" << endl ;

            semesterHours = 0 ;

            gpa = 0.0 ;

            name[ 0 ] = '' ;

        }

        Student( char *pName )

        {

            cout << "Конструктор Student( " << pName

                   <<" )" << endl ;

            strncpy( name , pName , MAXNAMESIZE ) ;

            name[ MAXNAMESIZE - 1 ] = '' ;

            semesterHours = 0 ;

            gpa = 0 ;

        }

        Student( char *pName , int xfrHours , float xfrGPA )

        {

            cout << "Конструктор Student( " << pName << ","

                    << xfrHours << "," << xfrGPA << " )" << endl ;

            strncpy( name , pName , MAXNAMESIZE ) ;

            name[ MAXNAMESIZE - 1 ] = '' ;

            semesterHours = xfrHours ;

            gpa = xfrGPA ;

        }

        ~Student( )

        {

            cout << "Деструктор Student" << endl ;

        }

      protected :

        char name[ 40 ] ;

        int semesterHours ;

        float gpa ;

    } ;

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

    {

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

        /* Вызов трёх разных конструкторов */

        Student noName ;

        Student freshman( "Marian Haste" ) ;

        Student xferStudent( "Pikumup Andropov" , 80 , 2.5 ) ;

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

        system( "PAUSE" ) ; return 0 ;

    }

Поскольку объект noName реализован без аргументов, он конструируется с использованием Student::Student( ), который называется конструктором по умолчанию или пустым конструктором. ( Я предпочитаю последнее название, но, поскольку первое более распространённое, в этой книге будет использоваться именно оно. ) Объект freshMan создаётся с использованием конструктора, которому нужен только один аргумент типа char*; объекту xfеr требуется конструктор с тремя аргументами.

Заметьте, что все три конструктора ( и особенно два последних ) очень похожи. Единственное отличие второго конструктора от третьего заключается в том, что он обнуляет поля semesterHours и gpa, в то время как третий конструктор может присваивать им передаваемые в качестве аргументов значения.

_________________

201 стр. Глава 17. Аргументация конструирования

С++ позволяет в объявлении функции указать значения аргументов по умолчанию, т.е. используемые в том случае, если программист их не указал. Если применить этот метод в третьем конструкторе, то все три конструктора можно объединить в один, как это сделано в представленной ниже программе.

    /* ConstructorWDefaults — несколько конструкторов */ 

    /*                        зачастую могут быть */

    /*                        бъединены в один */

    #include <cstdio>

    #include <cstdlib>

    #include <iostream>

    #include <strings.h>

    using namespace std ;

    const int MAXNAMESIZE = 40 ;

    class Student

    {

      public :

        Student( char *pName = "no name" ,

                        int xfrHours = 0 ,

                        float xfrGPA = 0.0 )

        {

            cout << "Конструктор Student( " << pName<< ","

                    << xfrHours << "," << xfrGPA << " )" << endl ;

            strncpy( name , pName , MAXNAMESIZE ) ;

            name[ MAXNAMESIZE - 1 ] = '' ;

            semesterHours = xfrHours ;

            gpa = xfrGPA ;

        }

        ~Student( )

        {

            cout << "Деструктор Student" << endl ;

        }

        /* ...прочие открытые члены... */

      protected :

        char name[ MAXNAMESIZE ] ;

        int semesterHours ;

        float gpa ;

    } ;

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

    {

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

        /* Вызов одного и того же конструктора */

        Student noName ;

        Student freshman( "Marian Haste" ) ;

        Student xferStudent( "Pikumup Andropov" , 80 , 2.5 ) ;

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

        system( "PAUSE" ) ; return 0 ;

    }

Теперь все три объекта строятся с помощью одного и того же конструктора, а значения по умолчанию используются для аргументов, отсутствующих в объектах freshMan и noName.

_________________

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

«В ранних версиях С++ вы не смогли бы создать конструктор по умолчанию, предусмотрев значения по умолчанию для всех аргументов. Конструктор по умолчанию должен был быть определён явно. Так что будьте готовы к тому, что некоторые старые версии компиляторов могут потребовать явного определения конструктора по умолчанию.»

[Помни!]