Учимся программировать на языке C++

ОГРАНИЧЕНИЕ КОЛИЧЕСТВА ДРУЗЕЙ


Как вы только что узнали, если вы объявляете один класс другом другого класса, вы обеспечиваете классу-другу доступ к частным элементам данных этого другого класса. Вы также знаете и то, что чем больше доступа к частным данным класса, тем больше шансов на внесение ошибок в программу. Следовательно, если доступ к частным данным другого класса необходим только нескольким функциям класса, C++ позволяет указать, что только определенные функции дружественного класса будут иметь доступ к частным элементам. Предположим, например, что класс librarian, представленный в предыдущей программе, содержит много разных функций. Однако предположим, что только функциям change_catalog и get_catalog необходим доступ к частным элементам класса book. Внутри определения класса book мы можем ограничить доступ к частным элементам только этими двумя функциями, как показано ниже:

class book

{

public:

book(char *, char *, char *);

void show_book(void);

friend char *librarian::get_catalog(book);

friend void librarian: :change_catalog( book *, char *);

private:

char title[64];

char author[ 64 ];

char catalog[64];

};



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

О функциях-друзьях

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

public:

friend class_name::function_name(parameter types);

Только функции-элементы, указанные как друзья, могут напрямую обращаться к частным элементам класса, используя оператор точку.

Если ваша программа начинает ссылаться на один класс из другого, вы можете получить синтаксические ошибки, если порядок определения классов неверен. В данном случае определение класса book использует прототипы функций, определенные в классе librarian. Следовательно, определение класса librarian должно предшествовать определению класса book. Однако если вы проанализируете класс librarian, то обнаружите, что он ссылается на класс book:


class librarian

{

public:

void change_catalog(book *, char *);

char *get_catalog(book);

};

Поскольку вы не можете поставить определение класса book перед определением класса librarian, C++ позволяет вам объявить класс book, тем самым сообщая компилятору, что такой класс есть, а позже определить его. Ниже показано, как это сделать:

class book; // объявление класса

Следующая программа LIMITFRI.CPP использует дружественные функции для ограничения доступа класса librarian к частным данным класса book. Обратите внимание на порядок определения классов:

#include iostream.h

#include string.h

class book;

class librarian

{

public:

void change_catalog(book *, char *);

char *get_catalog(book);

};

class book

{

public:

book(char *, char *, char *) ;

void show_book (void);

friend char *librarian::get_catalog(book);

friend void librarian::change_catalog( book *, char *);

private:

char title[64];

char author[64];

char catalog[64];

};

book::book(char *title, char *author, char *catalog)

{

strcpy(book::title, title);

strcpy(book::author, author);

strcpy(book::catalog, catalog);

}

void book::show_book(void)

{

cout "Название: " title endl;

cout "Автор: " author endl;

cout "Каталог: " catalog endl;

}

void librarian::change_catalog(book *this_book, char *new_catalog)

{

strcpy(this_book-catalog, new_catalog) ;

}

char *librarian::get_catalog(book this_book)

{

static char catalog[64];

strcpy(catalog, this_book.catalog);

return(catalog) ;

}

void main(void)



{

book programming( "Учимся программировать на C++", "Jamsa", "P101");

librarian library;

programming.show_book();

library.change_catalog(programming, "Легкий C++ 101");

programming.show_book();

}

Как видите, программа сначала использует объявление, чтобы сообщить компилятору, что класс book будет определен позже. Поскольку объявление извещает компилятор о классе book, определение класса librarian может ссылаться на класс book, который еще не определен в программе.

Что такое идентификатор класса

Идентификатор представляет собой имя, например имя переменной или класса. Если ваши программы используют дружественные классы, то может случиться, что определение одного класса ссылается на другой класс (его имя или идентификатор), о котором компилятор C++ еще ничего не знает. В таких случаях компилятор C++ будет сообщать о синтаксических ошибках. Чтобы избавиться от ошибок типа "что следует определять сначала", C++ позволяет вам включать в начало исходного текста программы объявление класса, тем самым вводя идентификатор класса:

class class_name;

Эта строка сообщает компилятору, что ваша программа позже определит указанный класс, а пока программе разрешается ссылаться на этот класс.


Содержание раздела