Читаем Справочное руководство по C++ полностью

Описание одного класса как друг другого класса дополнительно подразумевает, что частные и защищенные члены класса, предлагающего дружбу, могут использоваться в классе, получающем ее, например:

class X {

 enum { a=100 };

 friend class Y;

};

class Y {

 int v[X::a]; // Y друг класса X

};

class Z {

 int v[X::a]; // ошибка: X::a недоступно

};

Если класс или функция, объявленные как друзья, не были описаны, их имена попадают в ту же область видимости, что и имя класса, содержащего описание friend (§R.9.1).

Функция, появившаяся первый раз в описании friend, считается эквивалентной функции, описанной как extern (§R.3.3, §R.7.1.1).

Если функция-друг определена в описании класса, она считается функцией со спецификацией inline и к ней применимо правило переноса определения функции для функций-членов (§R.9.3.2). Функция-друг, определенная в описании класса, относится на лексическом уровне к области видимости этого класса. Для функции-друга, определенной вне класса, это не так.

На описание friend не влияет указание спецификаций-доступа (§R.9.2).

Понятие дружбы не является ни наследуемым, ни транзитивным.

Подтвердим это примером:

class A {

 friend class B;

 int a;

};

class B {

 friend class C;

};

class C {

 void f(A* p);

 {

  p-›a++; // ошибка: C не друг класса A, хотя

   // является другом друга класса A

 }

};

class D: public B {

 void f(A* p)

 {

  p-›a++; // ошибка: D не друг класса A, хотя

   // является производным друга класса A

 }

};

<p>R.11.5 Доступ к защищенным членам</p>

Друг или функция-член производного класса имеет доступ к защищенному статическому члену базового класса. Друг или функция-член производного класса могут получить доступ к защищенному нестатическому члену одного из своих базовых классов только через указатель, ссылку или объект производного класса (или любого класса, являющегося производным по отношению к нему). Рассмотрим пример:

class B {

protected:

 int i;

};

class D1: public B {

};

class D2: public B {

 friend void fr(B*, D1*, D2*);

 void mem(B*, D1*);

};

void fr(B* pb, D1* p1, D2* p2)

{

 pb-›i = 1; // недопустимо

 p1-›i = 2; // недопустимо

 p2-›i = 3; // нормально (обращение через D2)

}

void D2::mem(B* pb, D1* p1)

{

 pb-›i = 1; // недопустимо

 p1-›i = 2; // недопустимо

 i = 3; // нормально (обращение через this)

}

void g(B* pb, D1* p1, D2* p2)

{

 pb-›i = 1; // недопустимо

 p1-›i = 2; // недопустимо

 p2-›i = 3; // недопустимо

}

<p>R.11.6 Доступ к виртуальным функциям</p>

Правила доступа (§R.11) к виртуальной функции определяются ее описанием и на них не влияют правила доступа к к функции, которая позднее будет подавлять ее. Приведем пример:

class B {

public:

 virtual f();

};

class D: public B {

private:

 f();

};

void f()

{

 D d;

 B* pb = &d

 D* pd = &d

 pb-›f(); // нормально: B::f() общий член

  // вызывается D::f()

 pd-›f(); // ошибка: D::f() частный член

}

Права доступа проверяются при самом вызове, используя тип выражения, обозначающее объект, для которого вызывается функция-член (в примере выше это B*). Доступ к функции-члену в классе, где она определена (D в примере выше), в общем случае неизвестен.

<p>R.11.7 Множественный доступ</p>

Если добраться до имени можно несколькими путями по графу, задающему множественное наследование, то право доступа этого имени считается максимальным из прав, получаемых на разных путях. Поясним это примером:

class W { public: void f(); };

class A: private virtual W {};

class B: public virtual W {};

class C: public A, public B {

 void f() { W::f(); } // нормально

};

Поскольку W::f() доступно в C::f() по пути, связанному с общим наследованием из B, обращение является законным.

<p>R.12 Специальные функции-члены</p>
Перейти на страницу:

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

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных