Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Глобальная перегрузка.





В C++ кроме двух известных вам разновидностей перегрузки (перегрузка в классе и дружественная перегрузка), существует еще одно понятие - глобальная перегрузка, осуществляемая во внешней области видимости.

Допустим, переменные a и b объявлены как объекты класса C. В классе C определен оператор C::operator+(C), поэтому

  a+b означает a.operator+(b)

Однако, также возможна глобальная перегрузка оператора +:

  C operator+(C,C) {....}

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

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

Тем не менее, глобальная перегрузка операторов обеспечивает симметрию, которая также обладает эстетической ценностью. Рассмотрим пример:

#include <iostream> using namespace std;   // класс "точка" class Point { // координаты точки int X; int Y; public:   // конструктор Point(int iX,int iY){ X=iX; Y=iY; }   //показ на экран void Show(){ cout<<"\n+++++++++++++++++++++\n"; cout<<"X = "<<X<<"\tY = "<<Y; cout<<"\n+++++++++++++++++++++\n"; }   // перегруженный оператор + // метод класса для ситуации Point+int Point&operator+(int d){ Point P(0,0); P.X=X+d; P.Y=Y+d; return P; } // функции доступа к // privat-членам без них // глобальная перегрузка невозможна int GetX() const{ return X; } int GetY() const{ return Y; } void SetX(int iX){ X=iX; } void SetY(int iY){ Y=iY; } };   // глобальная перегрузка // для ситуации int + Point // доступ к private-членам // через специальные функции Point&operator+(int d,Point&Z){ Point P(0,0); P.SetX(d+Z.GetX()); P.SetY(d+Z.GetY()); return P; }   void main() { // создание объекта Point A(3,2); A.Show();   //оператор-метод + Point B=A+5; B.Show();   //глобальный оператор Point C=2+A; C.Show(); }

Без глобальной перегрузки задача int + Point не решается. Поскольку мы не можем получить доступ к "родному” целому типу (то есть к типу int) и переопределить его операции, обеспечить симметрию простым определением операторов класса не удастся. Потребуется решение с глобальными функциями.

Примечание:Здесь мы могли бы применить дружественную перегрузку, и таким образом избавиться от "функций доступа к private-членам". Однако, если бы тело класса Point было бы для нас закрыто, то вписать в него функцию-друга было бы нереально.

Перегрузка ввода/вывода данных.

Для того, что бы закрепить новую полученную информацию о перегрузке рассмотрим возможность перегрузить операторы << и >>. Для начала немного информации -

Выполнение любой программы С++ начинаются с набором предопределенных открытых потоков, объявленных как объекты классов в файле-библиотеке iostream. Среди них есть два часто используемых нами объекта - это cin и cout.

cin - объект класса istream (Потоковый класс общего назначения для ввода, являющийся базовым классом для других потоков ввода)

cout - объект класса ostream (Потоковый класс общего назначения для вывода, являющийся базовым классом для других потоков вывода)

Вывод в поток выполняется с помощью операции, которая является перегруженной операцией сдвига влево <<. Левым ее операндом является объект потока вывода. Правым операндом может являться любая переменная, для которой определен вывод в поток. Например, оператор cout << "Hello!\n"; приводит к выводу в предопределенный поток cout строки "Hello!".

Для ввода информации из потока используется операция извлечения, которой является перегруженная операция сдвига вправо >>. Левым операндом операции >> является объект класса istream.

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

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

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

3. Чтобы разрешить доступ к закрытым данным класса, операции ввода и вывода должны быть объявлены как дружественные функции класса.

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

Итак, рассмотрим пример подобной перегрузки:

  #include <iostream> using namespace std;   // класс "точка" class Point { // координаты точки int X; int Y; public:   // конструктор Point(int iX,int iY){ X=iX; Y=iY; } // дружественные функции перегрузки ввода и вывода данных friend istream& operator>>(istream& is, Point& P); friend ostream& operator<<(ostream& os, const Point& P);   }; //ввод данных через поток istream& operator>>(istream&is, Point&P){ cout<<"Set X\t"; is >> P.X; cout<<"Set Y\t"; is >> P.Y; return is; } //вывод данных через поток ostream& operator<<(ostream&os, const Point&P){ os << "X = " << P.X << '\t'; os << "Y = " << P.Y << '\n'; return os; }   void main() { // создание объекта Point A(0,0);   // одиночный ввод и вывод cin>>A; cout<<A;   // множественное выражение Point B(0,0); cin>>A>>B; cout<<A<<B; }

Примечание:Кстати!!! В одном из примеров мы использовали константный метод - метод, который не имеет право изменять поля класса. Однако, если какое-то поле объявлено со спецификатором mutable, его значение МОЖНО менять в методе типа const.







Дата добавления: 2015-10-01; просмотров: 344. Нарушение авторских прав; Мы поможем в написании вашей работы!




Картограммы и картодиаграммы Картограммы и картодиаграммы применяются для изображения географической характеристики изучаемых явлений...


Практические расчеты на срез и смятие При изучении темы обратите внимание на основные расчетные предпосылки и условности расчета...


Функция спроса населения на данный товар Функция спроса населения на данный товар: Qd=7-Р. Функция предложения: Qs= -5+2Р,где...


Аальтернативная стоимость. Кривая производственных возможностей В экономике Буридании есть 100 ед. труда с производительностью 4 м ткани или 2 кг мяса...

Тема: Составление цепи питания Цель: расширить знания о биотических факторах среды. Оборудование:гербарные растения...

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

Типовые примеры и методы их решения. Пример 2.5.1. На вклад начисляются сложные проценты: а) ежегодно; б) ежеквартально; в) ежемесячно Пример 2.5.1. На вклад начисляются сложные проценты: а) ежегодно; б) ежеквартально; в) ежемесячно. Какова должна быть годовая номинальная процентная ставка...

Пункты решения командира взвода на организацию боя. уяснение полученной задачи; оценка обстановки; принятие решения; проведение рекогносцировки; отдача боевого приказа; организация взаимодействия...

Что такое пропорции? Это соотношение частей целого между собой. Что может являться частями в образе или в луке...

Растягивание костей и хрящей. Данные способы применимы в случае закрытых зон роста. Врачи-хирурги выяснили...

Studopedia.info - Студопедия - 2014-2025 год . (0.012 сек.) русская версия | украинская версия