|
Программирование >> Инициализация объектов класса, структура
int operator+( int, int ); double operator+( double, double ); T* operator+( T*, I ); T* operator+( I, T* ); Первое объявление относится к встроенному оператору для сложения двух значений целых типов, второе - к оператору для сложения значений типов с плавающей точкой. Третье и четвертое соответствуют встроенному оператору сложения указательных типов, который используется для прибавления целого числа к указателю. Два последних объявления представлены в символическом виде и описывают целое семейство встроенных операторов, которые могут быть выбраны компилятором на роль кандидатов при обработке операций сложения. Любое из первых чет1рех множеств может оказаться пустым. Например, если среди членов класса SmallInt нет функции с именем operator+() , то четвертое множество будет пусто. Все множество операторных функций-кандидатов является объединением пяти namespace NS { class myFloat { myFloat( double ) ; class SmallInt { friend SmallInt operator+( const SmallInt &, int ) { /* ... */ } public: SmallInt( int ); operator int(); SmallInt operator+ ( const myFloat & ); ... SmallInt operator+ ( const SmallInt &, double ); int main() { тип si - class SmallInt: Этот класс объявлен в пространстве имен NS NS::SmallInt si(15); int res = si + 5.66; какой operator+()? return 0; подмножеств, описанных выше: В эти пять множеств входят семь операторных функций-кандидатов на роль operator+() в main() : первое множество пусто. В глобальной области видимости, а именно в ней употреблен operator+() в функции main() , нет объявлений перегруженного оператора operator+() ; второе множество содержит операторы, объявленные в пространстве имен NS, где определен класс SmallInt. В этом пространстве имеется один оператор: NS::SmallInt NS::operator+( const SmallInt &, double ); int operator+( int, int ); double operator+( double, double ); T* operator+( T*, I ); пятое множество содержит встроенные бинарные операторы: T* operator+( I, T* ); Да, формирование множества кандидатов для разрешения оператора, использованного с применением операторного синтаксиса, утомительно. Но после того как оно построено, устоявшие функции и наилучшая из них находятся, как и прежде, путем анализа преобразований, применимых к операндам отобранных кандидатов. 15.12.2. Устоявшие функции Множество устоявших операторных функций формируется из множества кандидатов путем отбора лишь тех операторов, которые могут быть вызваны с заданными операндами. Например, какие из семи найденных выше кандидатов устоят? Оператор NS::SmallInt si(15); использован в следующем контексте: si + 5.66; Левый операнд имеет тин SmallInt, а правый - double. Первый кандидат является устоявшей функцией для данного использования operator+() : NS::SmallInt NS::operator+( const SmallInt &, double ); Левый операнд типа SmallInt в качестве инициализатора точно соответствует формальному параметру-ссылке этого перегруженного оператора. Правый, имеющий тип double, также точно соответствует второму формальному параметру. Следующая функция-кандидат также устоит: NS::SmallInt NS::operator+( const SmallInt &, int ); Левый операнд si типа SmallInt в качестве инициализатора точно соответствует формальному параметру-ссылке перегруженного оператора. Правый имеет тип int и третье множество содержит операторы, объявленные друзьями класса SmallInt. Сюда входит NS::SmallInt NS::operator+( const SmallInt &, int ); четвертое множество содержит операторы, объявленные членами SmallInt. Такой тоже есть: NS::SmallInt NS::SmallInt::operator+( const myFloat & ); int operator+( int, int ); Четвертой и пятой устоявшими функциями являются встроенные операторы: double operator+( double, double ); Класс SmiallInt содержит конвертер, который может привести значение типа SmiallInt к типу int. Этот конвертер используется вместе с первым встроенным оператором для преобразования левого операнда в тип int. Второй операнд типа double трансформируется в тип int с помощью стандартного преобразования. Что касается второго встроенного оператора, то конвертер приводит левый операнд от типа SmallInt к типу int, после чего результат стандартно преобразуется в double. Второй же операнд типа double точно соответствует второму параметру. Лучшей из этих пяти устоявших функций является первая, operator+() , объявленная в пространстве имен NS: NS::SmallInt NS::operator+( const SmallInt &, double ); Оба ее операнда точно соответствуют параметрам. 15.12.3. Неоднозначность Наличие в одном и том же классе конвертеров, выполняющих неявные преобразования во встроенные типы, и перегруженных операторов может приводить к неоднозначности при выборе между ними. Например, есть следующее определение класса String с функцией class String { ... public: String( const char * = 0 ); bool operator== ( const String & ) const; нет оператора operator== ( const char * ) сравнения: и такое использование оператора operator==: может быть приведен к типу второго формального параметра с помощью стандартного преобразования. Устоит и третья функция-кандидат: NS::SmallInt NS::SmallInt::operator+( const myFloat & ); Левый операнд si имеет тип SmallInt, т.е. тип того класса, членом которого является перегруженный оператор. Правый имеет тип int и приводится к типу класса myFloat с помощью определенного пользователем преобразования в виде конструктора myFloat(double) .
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |