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

1 ... 252 253 254 [ 255 ] 256 257 258 ... 395


void mf( double ); void mf( char, char = \n );

mf(double) устояла потому, что у нее только один параметр и существует стандартное преобразование аргумента iobj типа int в параметр типа double;

mf(char,char) устояла потому, что для второго параметра имеется значение по умолчанию и существует стандартное преобразование аргумента iobj типа int в тип char первого формального параметра.

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

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

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

class myClass {

public:

static void mf( int );

char mf( char );

int main() { char cobj;

myClass::mf( cobj ); какая именно функция-член?

статические, так и нестатические члены:

Здесь функция-член mif() вызывается с указанием имени класса и оператора разрешения области видимости myClass::mif(). Однако не задан ни объект (с оператором точка ), ни указатель на объект (с оператором стрелка ). Несмотря на это, нестатическая функция-член mf(char) все же включается в множество устоявших наряду со статическим членом mf(int) .

Затем процесс разрешения перегрузки продолжается: на основе ранжирования преобразований типов, примененных к фактическим аргументам, чтобы выбрать наилучшую из устоявших функций. Аргумент cobj типа char точно соответствует формальному параметру mf(char) и может быть расширен до типа формального параметра mf(int) . Поскольку ранг точного соответствия выше, то выбирается функция mf(char) .

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



class myClass {

public:

static void mf( int* ); void mf( double ); void mf( int ) const;

...

функции-члены:

Тогда и статическая функция-член mf(int*) , и константная функция mf(int) , и неконстантная функция mf(double) включаются в множество кандидатов для

int main() {

const myClass mc;

double dobj;

mc.mf( dobj

mc.mf( dobj ); какая из функций-членов mf()?

показанного ниже вызова. Но какие из них войдут в множество устоявших?

Исследуя преобразования, которые надо применить к фактическим аргументам, м1 обнаруживаем, что устояли функции mf(double) и mf(int) . Тип double фактического аргумента dobj точно соответствует типу формального параметра mf(double) и может быть приведен к типу параметра mf(int) с помощью стандартного преобразования.

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

mc - это константный объект, для которого можно вызывать только нестатические константные функции-члены. Следовательно, неконстантная функция-член mf(double) исключается из множества устоявших, и остается в нем единственная функция mf(int) , которая и вызывается.

А если константный объект использован для вызова статической функции-члена? Ведь для такой функции нельзя задавать спецификатор const или volatile, так можно ли ее

class myClass { public:

static void mf( int ); char mf( char );

int main() {

const myClass mc; int iobj;

mc.mf( iobj ); можно вызать статически функцию-член?

вызывать через константный объект?

Еще одна особенность функций-членов, которую надо принимать во внимание при формировании множества устоявших функций, - это наличие спецификаторов const или volatile у нестатических членов. (Они рассматривались в разделе 13.3.) Как они влияют на процесс разрешения перегрузки? Пусть в классе myClass есть следующие



15.12. Разрешение перегрузки и операторы A

В классах могут быть объявлены перегруженные операторы и конвертеры. Предположим,

SomeClass sc;

при инициализации встретился оператор сложения:

int iobj = sc + 3;

Как компилятор решает, что следует сделать: вызвать перегруженный оператор для класса SomeClass или конвертировать операнд sc во встроенный тип, а затем уже воспользоваться встроенным оператором?

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

При разрешении перегрузки используется все та же процедура из трех шагов, представленная в разделе 9.2:

1. Отбор функций-кандидатов.

2. Отбор устоявших функций.

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

Разрешение перегрузки функции не применяется, если все операнды имеют встроенные типы. В таком случае гарантированно употребляется встроенный оператор. (Использование операторов с операндами встроенных типов описано в главе 4.) Например:

Статические функции-члены являются общими для всех объектов одного класса. Напрямую они могут обращаться только к статическим членам класса. Так, нестатические члены константного объекта mc недоступны статической mf(int) . По этой причине разрешается вызывать статическую функцию-член для константного объекта с помощью операторов точка или стрелка .

Таким образом, статические функции-члены не исключаются из множества устоявших и при наличии спецификаторов const или volatile у объекта, для которого они вызваны. Статические функции-члены рассматриваются как соответствующие любому объекту или указателю на объект своего класса.

В примере выше mc - константный объект, поэтому функция-член mif(char) исключается из множества устоявших. Но функция-член mf(int) в нем остается, так как является статической. Поскольку это единственная устоявшая функция, она и оказывается наилучшей.



1 ... 252 253 254 [ 255 ] 256 257 258 ... 395

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