Если класс объявлен как принадлежащий base class другому классу с использованием public спецификатора доступа, public члены базового класса доступны как public члены производного класса, а protected члены базового класса доступны как protected члены производного класса. Если класс объявлен базовый класс для другого класса , используя protected спецификатор доступа, то public и protected члены базового класса доступны в качестве protected членов производного класса. Если класс объявлен базовый класс для другого класса , используя private спецификатор доступа, то public и protected члены базового класса доступны в качестве private членов производного класса114.
При отсутствии access-specifier для базового класса public предполагается, когда производный класс определяется с помощью, class-key struct и private предполагается, когда класс определяется с помощью class-key class. [ Example:
class B { /* ... */ }; class D1 : private B { /* ... */ }; class D2 : public B { /* ... */ }; class D3 : B { /* ... */ }; // B private by default struct D4 : public B { /* ... */ }; struct D5 : private B { /* ... */ }; struct D6 : B { /* ... */ }; // B public by default class D7 : protected B { /* ... */ }; struct D8 : protected B { /* ... */ };
Вот B это общественная база D2, D4и D6, собственная база D1, D3и D5, и защищенная база D7 и D8. ] — end example
[ Note: Член частного базового класса может быть недоступен как унаследованное имя члена, но доступен напрямую. Из-за правил для pointer conversions и explicit castsпреобразование указателя на производный класс в указатель на недоступный базовый класс может быть плохо сформированным, если используется неявное преобразование, но правильно сформированным, если используется явное приведение. Например,
class B { public: int mi; // non-static member static int si; // static member }; class D : private B { }; class DD : public D { void f(); }; void DD::f() { mi = 3; // error: mi is private in D si = 3; // error: si is private in D ::B b; b.mi = 3; // OK (b.mi is different from this->mi) b.si = 3; // OK (b.si is different from this->si) ::B::si = 3; // OK ::B* bp1 = this; // error: B is a private base class ::B* bp2 = (::B*)this; // OK with cast bp2->mi = 3; // OK: access through a pointer to B. }
— end note ]
Базовый класс B из N находится accessible в R, если
изобретенный публичный член B мог бы быть публичным членом N, или
R происходит в члене или друге класса N, а изобретенный публичный член B мог бы быть частным или защищенным членом N, или
R происходит в члене или друге класса, P производного от N, и изобретенный открытый член B будет частным или защищенным членом P, или
существует такой класс S , который B является базовым классом, S доступным в, R и S базовым классом, N доступным в R.
[ Example:
class B { public: int m; }; class S: private B { friend class N; }; class N: private S { void f() { B* p = this; // OK because class S satisfies the fourth condition above: B is a base class of N // accessible in f() because B is an accessible base class of S and S is an accessible // base class of N. } };
— end example ]
Если базовый класс доступен, можно неявно преобразовать указатель на производный класс в указатель на этот базовый класс ([conv.ptr], [conv.mem]). [ Note: Отсюда следует, что члены и друзья класса X могут неявно преобразовывать X* в указатель на частный или защищенный непосредственный базовый класс X. ] Доступ к члену зависит от класса, в котором член назван. Этот класс именования - это класс, в котором имя члена было просмотрено и найдено. [ Этот класс может быть явным, например, когда используется, или неявным, например, когда используется оператор (включая случаи, когда добавляется неявный « »). Если оба операторы доступа члена класса и используется , чтобы назвать элемент (как в ), классе именования элемента является классом обозначать те из (то есть ). ] Член доступен в момент, когда назван в классе, если — end note Note: qualified-id class member access this->qualified-idp->T::mnested-name-specifierqualified-idT — end note mRN
m как участник N является публичным, или
m как член N является частным и R встречается в члене или друге класса N, или
m поскольку член N защищен и R встречается в члене или друге класса N, или в члене класса, P производного от N, где m как член P является общедоступным, частным или защищенным, или
существует базовый класс B в N который доступен на R, и m доступен в R когда названный в классе B. [ Example:
class B;
class A {
private:
int i;
friend void f(B*);
};
class B : public A { };
void f(B* p) {
p->i = 1; // OK: B* can be implicitly converted to A*, and f has access to i in A
}
— end example ]
Если оператор доступа к члену класса, включая неявный «this->», используется для доступа к нестатическому члену данных или нестатической функции-члену, ссылка имеет неправильный формат, если левый операнд (рассматриваемый как указатель в.операторе « » case) нельзя неявно преобразовать в указатель на класс именования правого операнда. [ Note: Это требование является дополнением к требованию, чтобы член был доступен с указанным именем. ] — end note
Как указано ранее в разделе [class.access], частные члены базового класса остаются недоступными даже для производных классов, если только friend объявления в определении базового класса не используются для явного предоставления доступа.