Программирование на С++

Страницы работы

Фрагмент текста работы

классам, она может ссылаться непо­средственно на данные-члены s1 и s2, закрытые в своих классах. Другие «недружественные» функции не име­ют такого доступа к скрытым членам этих классов.

Дружественные функции-члены

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

Листинг 4.3. FRIENDMF.CPP (использование дружественных функций-членов)

 1:  #include <iostream.h>

 2:     

 3:  class One;  // Неполное объявление класса

 4:     

 5:  class Two { 

 6:  private: 

 7:    char *s2; // Доступен членам класса Two

 8:  public: 

 9:    Two() { s2 = "one, two, three"; }

10:    void Show(One &c1);

11:  }; 

12:     

13:  class One { 

14:    friend void Two::Show(One &c1);

15:  private: 

16:    char *s1; // Доступен в классе One и в Two::Show

17:  public: 

18:    One() { s1 = "Testing "; }

19:    }; 

20:     

21:  int main() 

22:  { 

23:    One c1;

24:   

25:    Two c2; 

26:    c2.Show(c1); 

27:    return 0; 

28:  } 

29:     

30:  void Two::Show(One &c1)

31:  { 

32:    cout << c1.s1 << s2 << ′\n′;

33:  } 

Как и в модуле FRIENDFN (листинг 4.2), в новой программе FRIENDMF объявляется два класса, One и Two. В классе One объявляется аналогичная дружественная функция-член (строка 14) с помощью имени класса и оператора разрешения области видимости (Two::), чтобы указать компилятору местонахождение функции Show().

Порядок объявления двух классов изменился по сравнению с приведенным в предыдущем листинге на об­ратный, поскольку класс, в котором содержится прототип функции-члена, должен объявляться до класса, указывающего функцию-член дружественной. Для класса One, объявляющего дружественной функцию Two::Show(), объявление класса Two уже должно быть доступно компилятору.

Еще одно отличие состоит в способе доступа к закрытым данным обоих классов в функции Show() (строки 30-33). Объявлен только один ссылочный параметр One &cl. Поскольку функция Show() – член класса Two, она имеет непосредственный доступ ко всем членам класса Two. Выражение cl.sl в операторе вывода в поток в строке 32 не является недозволенным, так как функция Show() дружественна классу One, которому принадлежит закрытый член s1. Функция-член Show() может ссылаться на s2 непосредственно, поскольку этот член принадлежит классу Two, в котором объявлена Show().

Поскольку функция Show() – член класса Two, в ней определен указатель this, ссылающийся на объект класса, для которого была вызвана функция-член. Поэтому в программе должен объявляться объект класса Two (строка 24), затем вызываться функция Show() для этого объекта (строка 26).

Перегрузка операторов

Тема перегрузки операторов едва ли не стала предметом суеверного поклонения. Проще говоря, перегрузка операторов позволяет определять действия для объектов класса в выражениях, использующих обычные опера­торы, такие как сложение (+) или вычитание (–). Вы можете объявить класс, подобный AnyClass, а затем и несколько объектов этого класса с соответствующим образом переопределенными операторами:

AnyClass c1, с2, с3;

Вы можете использовать эти объекты в выражениях вида:

с3 = с1 + с2;

Для лучшего понимания сути перегрузки операторов полезно провести ревизию того, что вам известно об операторах вообще. Конечно, обычный оператор знак плюс (+) суммирует два значения. Знак минус (–) осу­ществляет операцию вычитания. Эти и другие символы называются бинарными операторами, поскольку им необходимы два аргумента. Другие, например оператор отрицания (!), – унарные, им требуется только один аргумент. Еще один пример – унарный минус (–). Выражение –count меняет знак значения count.

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

Перегрузка функций-операторов

Простой пример иллюстрирует перегрузку операторов для гипотетического класса с именем ZZ:

class ZZ {

public:

  friend ZZ operator+(ZZ a, ZZ b);

  friend ZZ operator-(ZZ a, ZZ b);

  friend ZZ operator*(ZZ a, ZZ b);

  friend ZZ operator/(ZZ a, ZZ b);

  // ... прочие открытые, защищенные и закрытые члены

};

В классе ZZ объявлены четыре перегруженные функции-оператора. (На практике в ZZ могут объявляться и другие открытые, защищенные и закрытые

Похожие материалы

Информация о работе