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

    void fn( MyClass&mc )

    {

        MyClass newMC( mc ) ; /* Здесь используется конструктор копирования */

        MyClass newerMC = mc ; /* Менее очевидно, что здесь также используется конструктор копирования */

        MyClass newestMC ; /* Создание объекта по умолчанию */

        newestMC = mc ; /* Присвоение */

    }

_________________

272 стр. Часть 5. Полезные особенности

Создание newMC следует стандартному шаблону создания нового объекта как зеркального отображения существующего с использованием копирующего конструктора MyClass( MyClass& ). Несколько менее очевидно, что объект newerMC также создаётся при помощи конструктора копирования. Запись MyClass а = b — всего лишь другой способ записи MyClass a( b ). То, что в первом варианте записи имеется символ "=", не приводит к вызову оператора присвоения. Однако в случае с объектом newestMC всё не совсем так. Сначала этот объект создаётся с использованием конструктора по умолчанию, а затем перезаписывается объектом mc с помощью оператора присвоения.

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

«Главное правило заключается в следующем: конструктор копирования используется при создании нового объекта, а оператор присвоения — если объект слева от символа присвоения уже существует.»

[Советы]

<p id="chapter23.4"><strong>►Переопределение оператора присвоения...273</strong></p>

Следующая программа демонстрирует переопределение оператора присвоения. В программе также представлен конструктор копирования — просто для сравнения.

    //

    /* DemoAssignmentOperator — демонстрация оператора */

    /*          присвоения для пользовательского класса */

    //

    #include

    #include

    #include

    #include

    using namespace std ;

    /* Name — класс для демонстрации присвоения и конструктора копирования */

    class Name

    {

      public :

        Name( char *pszN = 0 )

        {

            copyName( pszN , " " ) ;

        }

        Name( Name& s )

        {

            cout << "Вызов конструктора копирования" << endl ;

            copyName( s.pszName , " ( copy ) " ) ;

        }

        ~Name( )

        {

            deleteName( ) ;

        }

        /* Оператор присвоения */

        Name&operator=( Name& s )

        {

            cout << "Выполнение присвоения" << endl ;

_________________

273 стр. Глава 23. Оператор присвоения

            /* Удаляем выделенную память... */

            deleteName( ) ;

            /* ...перед заменой её новым блоком */

            copyName( s.pszName , " ( replaced ) " ) ;

            /* Возвращаем ссылку  на существующий объект */

            return *this ;

        }

        /* Очень простая функция доступа */

        char* out( ) { return pszName ; }

      protected :

        void copyName( char* pszN , char* pszAdd ) ;

        void deleteName( ) ;

        char *pszName ;

    } ;

    /* copyName( ) — Выделение памяти из кучи и сохранение строк в ней */

    void Name::copyName( char* pszN , char* pszAdd )

    {

        pszName = 0 ;

        if ( pszN )

        {

            pszName = new char[ strlen( pszN ) +

                               strlen( pszAdd ) + 1 ] ;

            strcpy( pszName , pszN ) ;

            strcat( pszName , pszAdd ) ;

        }

    }

    /* deleteName( ) — возврат памяти в куче */

    void Name::deleteName( )

    {

        if ( pszName )

        {

            delete pszName ;

            pszName = 0 ;

        }

    }

Перейти на страницу:

Все книги серии Для чайников

Похожие книги