2011 C++ 標準は、セクション 11.4 で次のように述べています。
非静的データメンバーまたは非静的メンバー関数がその命名クラス (11.2) の保護されたメンバーである場合、条項 11 で前述したものを超える追加のアクセスチェックが適用されます。参照は、一部のクラス C のフレンドまたはメンバーで発生します。アクセスがメンバーへのポインターを形成することである場合 (5.3.1)、nested-name-specifier は C または C から派生したクラスを示すものとします。他のすべてのアクセスには、(おそらく暗黙的な) オブジェクト式 ( 5.2.5 ) が含まれます。この場合、オブジェクト式のクラスは C または C から派生したクラスでなければなりません。
(旧規格では、同様の文言がセクション 11.5 にありました。)
このルールは、「B の保護されたメンバーは、任意の B または B の派生クラスからアクセスできる」というよく繰り返される考えを制限します。ただし、現在のコンパイラが異なれば規則の適用方法も異なるという事実から明らかなように、規則の解釈は困難です。
たとえば、このテスト コードを参照してください。このコードは、Apple LLVM Compiler 4.1、GCC 4.7.2、および Visual Studio 2010 を使用してコンパイルしました。報告されるエラーには類似点と相違点があります。
class Base
{
protected:
int A;
};
class Derived : public Base
{
protected:
int B;
};
class Grandchild : public Derived
{
void access_protected(Base* b, Derived* d,
Grandchild* g, class GreatGrandchild* gg );
};
class GreatGrandchild : public Grandchild {};
void Grandchild::access_protected(Base* b, Derived* d,
Grandchild* g, GreatGrandchild* gg )
{
int* p;
Base lb;
Derived ld;
Grandchild lg;
GreatGrandchild lgg;
A = 1; // Legal...
B = 2;
Base::A = 1;
Derived::B = 2;
b->A = 1; // Illegal ALL
p = &(b->A); // Illegal ALL
lb.A = 1; // Illegal ALL
p = &(lb.A); // Illegal ALL
d->A = 1; // Illegal GCC, VS
p = &(d->A); // Illegal GCC, VS
ld.A = 1; // Illegal GCC, VS
p = &(ld.A); // Illegal GCC, VS
d->B = 2; // Illegal ALL
p = &(d->B); // Illegal ALL
ld.B = 2; // Illegal ALL
p = &(ld.B); // Illegal ALL
g->A = 1; // Legal...
g->B = 2;
lg.A = 1;
lg.B = 2;
gg->A = 1;
gg->B = 2;
lgg.A = 1;
lgg.B = 2;
}
これらの結果から、(1) 独自のクラスおよび派生クラスの保護されたメンバーにアクセスすることは常に問題ありません。(2) 宣言された基本クラスの保護されたメンバーにアクセスすることは、そのクラス以外からは常に違法です。(3) 標準はメンバーへのポインタと「オブジェクト式」を区別するように注意していますが、標準とコンパイラの両方が同じ制限を与えています。Derived
(4)メンバーが中間のベースで宣言された「中間」基本クラス (例) の保護されたメンバーにアクセスすることが合法であるかどうかは不明です。
混乱するのは、祖父母の保護されたメンバーを私の親が所有していると私が話してもよいかどうかということです。ダブルミーニングは意図されていません。
friends
(単純さと正気のために無視しています。)
言語の基本的な部分なのでprotected
、よく理解したいと思っています。お願いします:
- 標準の解釈に基づいて、どのコンパイラがこれを正しく実装していますか?
- 全体的な制限の根拠は何ですか? 基本クラスの保護されたメンバーに自由にアクセスできないのはなぜですか? 回避するために設計された具体的なエラーは何ですか? この理論的根拠を探るオンライン ディスカッション (理想的には標準化委員会が開催するもの) を知っていますか?