通常、「using」宣言は、そうでなければ隠される基底クラスの一部のメンバー関数をスコープに入れるために使用されます。その観点からは、アクセス可能な情報をより便利に使用するためのメカニズムにすぎません。
ただし、'using' 宣言を使用して、アクセス制約を変更することもできます (関数だけでなく、属性に対しても)。例えば:
class C{
public:
int a;
void g(){ cout << "C:g()\n"; }
C() : a(0){}
};
class D : public C{
private:
using C::a;
using C::g;
public:
D() { a = 1; }
};
int main(void){
D d;
cout << d.a << endl; //error: a is inaccessible
C *cp = &d;
cout << cp->a << endl; //works
d.g(); //error: g is inaccessible
cp->g(); //works
return 0;
}
基本クラスへのポインターからいつでも g() と a にアクセスできるため、派生クラスでのこのアクセス制限は実際には役に立たないと思います。では、少なくとも何らかのコンパイラ警告が表示されるべきではないでしょうか? それとも、派生クラスによるアクセスの制限を禁止する方がよいのではないでしょうか? using 宣言は、アクセスに制約を追加する唯一の可能性ではありません。また、基本クラスの関数をオーバーライドして、より多くのアクセス制限を持つセクションに配置することによっても実行できます。そのような方法でアクセスを制限することが本当に必要な合理的な例はありますか? そうでない場合、なぜそれを許可する必要があるのか わかりません。
もう 1 つ: 少なくとも g++ では、同じコードは「using」という単語がなくても適切にコンパイルされます。つまり、上記の例では、C::a; と書くことができます。および C::g; C::a; を使用する代わりに C::g を使用して; 最初のものは後者の近道にすぎないのでしょうか、それとも微妙な違いがありますか?
//編集:
したがって、以下の議論と回答から、私の結論は次のようになります:
- public 継承を使用して派生クラスのアクセス制約を制限することが許可されています-
使用できる便利な例があります
- テンプレートと組み合わせて使用すると問題が発生する可能性があります (たとえば、派生クラスは、それがベースであるにもかかわらず、一部のテンプレートクラス/関数の有効なパラメーターになることはできません)
- よりクリーンな言語設計では、そのような使用を許可しないでください
- コンパイラーは少なくとも何らかの警告を発行する可能性があります