![]() |
|
Программирование >> Инициализация объектов класса, структура
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) в нем остается, так как является статической. Поскольку это единственная устоявшая функция, она и оказывается наилучшей.
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |