Программирование >>  Инициализация объектов класса, структура 

1 ... 248 249 250 [ 251 ] 252 253 254 ... 395


SmallInt si(15);

Предположим, что имеется такой вызов:

add( si, 566 );

Функция-кандидат должна иметь имя add. Какие из объявлений add() принимаются во внимание? Те, которые видимо: в точке вызова.

Например, обе функции add() , объявленные в глобальной области видимости, будут

const matrix& add( const matrix &, int );

double add( double, double );

int main() {

SmallInt si(15); add( si, 566 ); ...

кандидатами для следующего вызова:

Рассмотрение функций, чьи объявления видны в точке вызова, производится не только для вызовов с аргументами типа класса. Однако для них поиск объявлений проводится еще в двух областях видимости:

если фактический аргумент - это объект типа класса, указатель или ссылка на тип класса либо указатель на член класса и этот тип объявлен в пользовательском

использование конструкторов при выполнении неявных преобразований (а значит, уменьшить вероятность неожиданных эффектов) можно путем объявления их явными.

15.10.1. Еще раз о разрешении перегрузки функций

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

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

В этом разделе мы детально рассмотрим, как фактические аргументы и формальные параметры типа класса влияют на отбор функций-кандидатов и как последовательности определенных пользователем преобразований сказываются на выборе наилучшей из устоявших функции.

15.10.2. Функции-кандидаты

Функцией-кандидатом называется функция с тем же именем, что и вызванная.



namespace NS {

class SmallInt { /* ... */ }; class String { /* ... */ };

String add( const String &, const String & );

int main() {

si имеет тип class SmallInt:

класс объявлен в пространстве имен NS

МЯ- - Ятя! 1 Tnt 4i MSI

NS::SmallInt si(15);

add( si, 566 ); NS::add() - функция-кандидат return 0;

объявленные в этом же пространстве и имеющие то же имя, что и вызванная:

Аргумент si имеет тин SmiallInt, т.е. тин класса, объявленного в пространстве имен NS. Поэтому к множеству функций-кандидатов добавляется add(const String &, const String &), объявленная в этом пространстве имен;

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

namespace NS { class SmallInt {

friend SmallInt add( SmallInt, int ) { /* ... */ }

int main() {

NS::SmallInt si(15);

add( si, 566 ); функция-друг add() - кандидат return 0;

вызванная функция, то они добавляются к множеству функций-кандидатов:

Аргумент функции si имеет тип SmallInt. Функция-друг класса SmallInt add(SmallInt, int) - член пространства имен NS, хотя непосредственно в этом пространстве она не объявлена. При обычном поиске в NS функция-друг не будет найдена. Однако при вызове add() с аргументом типа класса SmallInt принимаются во внимание и добавляются к множеству кандидатов также друзья этого класса, объявленные в списке его членов.

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

Рассмотрим следующий пример:

пространстве имен, то к множеству функций-кандидатов добавляются функции,



namespace NS {

class SmallInt {

friend SmallInt add( SmallInt, int ) { /* ... */ }

class String { /* ... */ };

String add( const String &, const String & );

const matrix& add( const matrix &, int );

double add( double, double );

int main() {

si имеет тип class SmallInt: класс объявлен в пространстве имен NS NS::SmallInt si(15);

add( si, 566 ); вызывается функция-друг return 0;

Здесь кандидатами являются:

const matrix& add( const matrix &, int )

глобальные функции:

double add( double, double )

функция из пространства имен:

NS::add( const String &, const String & )

функция-друг:

NS::add( SmallInt, int )

При разрешении перегрузки выбирается функция-друг класса SmallInt NS::add( SmallInt, int ) как наилучшая из устоявших: оба фактических аргумента точно соответствуют заданным формальным параметрам.

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

15.10.3. Функции-кандидаты для вызова функции в области видимости класса

Когда вызов функции вида



1 ... 248 249 250 [ 251 ] 252 253 254 ... 395

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика