    Скомпилируйте и запустите на выполнение модифицированную программу. Как вы 
видите, выражение заменено на операцию отрицания длинного целого представления 
строкового члена а. Вы научили C++ вьполнять операцию отрицания над длинными 
целыми значениями, представленными в строковой форме! 
    Как и в случае с перегруженными бинарными операторами, вы можете объявить 
перегруженные унарные операторы функциями-членами. Беря за основу первоначальную 
копию STROPS2.CPP, добавьте следующее объявление над строкой 14 (перед 
закрывающей скобкой класса TStrOp): 

    long operator-(void); 

    Это объявление функции-члена похоже на объявление предыдущей дружественной 
унарной функции поскольку все функции-члены получают указатель this, новая 
функция-член operator-() объявляется без параметров и оперирует непосредственно 
длинным целым эквивалентом значения this->value. Это демонстрируется в реализации 
функции, которую вы можете вставить после функции main(): 

    long TStrOp: :operator-(void) { 

    return -atol(value);    // аналогично -atol(this->value) 

   } 


    Перегруженная функция-член возвращает длинное целое значение value с 
обратным знаком. Его можно пользовать в выражениях, подобных следующему, 
которые можно вставить в функцию main(): 

    cout « "\n-a    == " « -а; 

    Преобразование типов 

    Вы можете определить свои собственные правила преобразования типов данных 
для автоматического преобразования объектов в другие типы. Например, 
предположим, вы объявили и инициализировали объекты класса TStrOp из 
STROPS2.CPP (листинг 15.5) следующим образом: 

    TStrOp myValue = "9876"; 

    Класс TStrOp запоминает строку, которая может использоваться как 
эквивалент длинного целого значения в операциях сложения и вычитания. Вы можете 
логически попытаться присвоить объект myValue переменной длинного целого типа: 

    long x = myValue;         // ???	

    Конечно, этот оператор не скомпилируется, поскольку в классе TStrOp не 
предусмотрено преобразования строки в длинное целое значение. Решение этой 
проблемы заключается в использовании перегрузки операции преобразования типов 
для преобразования объекта класса TStrOp к другому типу данных. 
    Операторы преобразования принимают форму оператора TYPE(), где TYPE — тип 
данных, к которому вы хотите преобразовать объект класса. Например, для задания 
правила преобразования типа объектов клас TStrOp в длинное целое вставьте 
следующую встраиваемую функцию внутрь открытой секции класса: 

    operator long() { return atol(value);  } 

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

    Оператор индексирования массива 

    Вы можете перегрузить оператор индексирования массива [] для реализации 
доступа к данным-членам класса, подобного доступу к элементам массива, даже 
если эти данные имеют вид отдельных членов или списка. В простом примере 
(листинг 15.6) демонстрируется перегрузка оператора [] для класса, запоминающе 
четыре целочисленных значения в виде отдельных данных-членов. 
    Несмотря на простоту, класс PseudoArray содержит все необходимые 
компоненты для перегрузки оператора индексирования массива. В классе 
объявляются четыре закрытых целочисленных члена в строках 5-8. В строке 13 
объявляется функция-член operator[] с одним беззнаковым параметром. Параметр 
служит индексjv в массиве и может иметь произвольный тип. 

    Листинг 15.6. SSOP.CPP (перегрузка оператора индексирования) 

    1:   #include <iostream.h> 
    2: 
    3:   class PseudoArray { 


    376     Часть III. Программирование на ANSI С+
