C++では、名前空間やクラス内のクラス、関数、変数にアクセスするために、演算子::
を使用します。
もし言語仕様が、オブジェクトのインスタンス変数やメソッドにアクセスするような場合にも、::
ではなく.
を使用したとしたら、::
にはない曖昧さが生じる可能性がありますか?
C++では型名を兼ねた変数名を認めていないので、そのようなケースは考えられません。
訂正します。なぜ.
ではなく::
が選ばれたのかを聞いているのではなく、それも可能だったのかを聞いているのです。
C++は、既存のCコード(オブジェクト名と構造体タグの名前の衝突を許容している)との互換性をほぼ確保しようとしたため、クラス名とオブジェクト名の名前の衝突を許容しています。
つまり、これは
struct data {
static int member;
};
struct data2 {
int member;
};
void f(data2& data) {
data.member = data::member;
}
が正当なコードであることがわかります。
両方とも有効だが、異なるオブジェクトを参照している例です。
#include <iostream>
A構造体{
int i;
};
構造体B {
int i;
A Bです。
};
int メイン() {
B x {0, 1};
std::cout << x.B.i << '⏺️です。
std::cout << x.B::i << '\n';
}
Live on coliru](//coliru.stacked-crooked.com/a/40e03237388e7c59)をご覧ください。
a::bと
a.bには違いがあります。
::は
a` が名前空間として使用されていることを意味し、これは名前空間または型名であることを意味します。C++が仮想ではない複数の継承をサポートしており、変数が同じ型を持つことができれば、間違ったオブジェクトを参照する可能性がなくなります。これはテンプレートメタプログラミングに必要です。
他の例としては、クラスBのコンテキストで、&B::foo
と&B.foo
を比較することができます。
Deduplicatorの例を拡張してみましょう。
#include <iostream>を使用しています。
構造体A {
i.
};
struct B : public A {
int i.
A A.
};
int main() {
B x {1, 2}.
std::cout << x.i << '\n'.
std::cout << x.B::i << '\n'; // 上の行と同じです。
std::cout << x.A.i << '\n'.
std::cout << x.A::i << '\n'; // 上の行と同じではない。
}
コリルビューワーでライブ】[1
の助けを借りて、どのメンバにアクセスしたいかを区別することができないため、親クラスで宣言されたメンバに同じ名前でアクセスすることができません。