#include

using namespace std;

const int IDLE=0;

const int INUSE=1;

class С2; // опережающее объявление

class C1 {

  int status; // IDLE если сообщение неактивно, INUSE если сообщение выведено на экран.

  // ...

 public:

  void set_status(int state);

  friend int idle(C1 a, C2 b);

};

class C2 {

  int status; // IDLE если сообщение неактивно, INUSE если сообщение выведено на экран.

  // ...

 public:

  void set_status(int state);

  friend int idle(C1 a, C2 b);

};

void C1::set_status(int state)

{

 status = state;

}

void C2::set_status(int state)

{

 status = state;

}

// Функция idle() - "друг" для классов C1 и C2.

int idle(C1 a, C2 b)

{

 if(a.status || b.status) return 0;

 else return 1;

}

int main()

{

 C1 x;

 C2 y;

 x.set_status(IDLE);

 у.set_status(IDLE);

 if(idle(x, y)) cout << "Экран свободен.\n";

 else cout << "Отображается сообщение.\n";

 x.set_status(INUSE);

 if(idle(x, y)) cout << "Экран свободен.\n";

 else cout << "Отображается сообщение.\n";

 return 0;

}

При выполнении программа генерирует такие результаты.

Экран свободен.

Отображается сообщение.

Поскольку функция idle() является "другом" как для класса С1, так и для класса С2, она имеет доступ к закрытому члену status, определенному в обоих классах. Таким образом, состояние объекта каждого класса одновременно можно проверить всего одним обращением к функции idle().

Опережающее объявление предназначено для объявления имени классового типа до определения самого класса.

Обратите внимание на то, что в этой программе используется опережающее объявление (также именуемое опережающей ссылкой) для класса С2. Его необходимость обусловлена тем, что объявление функции idle() в классе С1 использует ссылку на класс С2 до его объявления. Чтобы создать опережающее объявление для класса, достаточно использовать формат, представленный в этой программе.

"Друг" одного класса может быть членом другого класса. Перепишем предыдущую программу так, чтобы функция idle() стала членом класса С1. Обратите внимание на использование оператора разрешения области видимости (или оператора разрешения контекста) при объявлении функции idle() в качестве "друга" класса С2.

/* Функция может быть членом одного класса и одновременно "другом" другого.

*/

#include

using namespace std;

const int IDLE=0;

const int INUSE=1;

class C2; // опережающее объявление

class C1 {

  int status; // IDLE, если сообщение неактивно, INUSE, если сообщение выведено на экран.

  // ...

 public:

  void set_status(int state);

  int idle(C2 b); // теперь это член класса C1

};

class C2 {

  int status; // IDLE, если сообщение неактивно, INUSE, если сообщение выведено на экран.

  // . . .

 public:

  void set_status(int state);

  friend int C1::idle(C2 b); // функция-"друг"

};

void C1::set_status(int state)

{

 status = state;

}

void C2::set_status(int state)

{

 status = state;

}

// Функция idle() -- член класса С1 и "друг" класса С2.

int C1::idle(С2 b)

{

 if(status || b.status) return 0;

 else return 1;

}

int main()

{

 C1 x;

 C2 y;

 x.set_status(IDLE);

 y.set_status(IDLE);

 if(x.idle(y)) cout << "Экран свободен.\n";

 else cout << "Отображается сообщение.\n";

Перейти на страницу:

Все книги серии Изучайте C++ с профессионалами

Похожие книги