476

変更する必要があるクラスで、次のコード行を見つけました。

::Configuration * tmpCo = m_configurationDB;//pointer to current db

クラス名の前に付けられた二重コロンが正確に何を意味するのかわかりません。tmpCoクラスのオブジェクトへのポインターとしての宣言Configuration...しかし、前に付けられた二重コロンは私を混乱させます。

私も見つけました:

typedef ::config::set ConfigSet;
4

9 に答える 9

562

これにより、現在の名前空間からではなく、グローバル名前空間から解決が行われることが保証されます。たとえば、次のように呼び出される 2 つの異なるクラスがあるとConfigurationします。

class Configuration; // class 1, in global namespace
namespace MyApp
{
    class Configuration; // class 2, different from class 1
    function blah()
    {
        // resolves to MyApp::Configuration, class 2
        Configuration::doStuff(...) 
        // resolves to top-level Configuration, class 1
        ::Configuration::doStuff(...)
    }
}

基本的に、別の名前空間 (この場合はMyApp.

于 2010-11-24T16:27:38.260 に答える
220

この::演算子はスコープ解決演算子と呼ばれ、まさにそれを行い、スコープを解決します。したがって、型名にこれをプレフィックスとして付けることで、コンパイラにその型のグローバル名前空間を調べるように指示します。

例:

int count = 0;

int main(void) {
  int count = 0;
  ::count = 1;  // set global count to 1
  count = 2;    // set local count to 2
  return 0;
}
于 2010-11-24T16:27:16.540 に答える
141

すでに合理的な答えがたくさんあります。一部の読者に役立つかもしれないアナロジーを紹介します。 実行したいプログラムのパスを検索するときに::、ファイルシステムのディレクトリ区切り記号 ' ' とよく似た働きをします。/検討:

/path/to/executable

これは非常に明示的です。有効な PATH に関係なく、ファイルシステム ツリー内の正確な場所にある実行可能ファイルのみがこの仕様に一致できます。同様に...

::std::cout

...C++ 名前空間「ツリー」でも同様に明示的です。

このような絶対パスとは対照的に、適切な UNIX シェル ( zshなど) を構成して、現在のディレクトリまたは環境変数の任意の要素の下の相対パスを解決できます。PATHPATH=/usr/bin:/usr/local/bin/tmp

X11/xterm

/tmp/X11/xterm...見つかった場合は喜んで実行/usr/bin/X11/xtermします/usr/local/bin/X11/xterm。同様に、 という名前空間Xにいて、using namespace Y有効な " " があるとします。

std::cout

...引数依存ルックアップ(ADL、別名 Koenig ルックアップ)により::X::std::cout、 、::std::cout::Y::std::cout、およびおそらく他の場所のいずれかで見つかる可能性があります。そのため、 onlyはあなたが意味するオブジェクトを正確に明示していますが、幸いなことに、正しい心の誰も「」と呼ばれる独自のクラス/構造体または名前空間を作成したり、「」と呼ばれるものを作成したりすることはないため、実際には only を使用しても問題ありません。::std::coutstdcoutstd::cout

注目すべき違い:

1) シェルは での順序付けを使用して最初の一致を使用する傾向がありPATHますが、あいまいな場合、C++ ではコンパイラ エラーが発生します。

2) C++ では、先行スコープのない名前を現在の名前空間で照合できますが、ほとんどの UNIX シェル.は、PATH.

3) C++ は常にグローバル名前空間を検索します (/暗黙的に yourを持つようにPATH)。

名前空間とシンボルの明示性に関する一般的な議論

絶対::abc::def::...「パス」を使用すると、使用している他の名前空間から分離するのに役立つ場合があります。これは、使用している名前空間の一部であり、コンテンツを実際に制御することはできません。また、ライブラリのクライアント コードも使用する他のライブラリからも分離できます。一方で、シンボルの既存の「絶対」位置により緊密に結び付けられ、名前空間での暗黙的なマッチングの利点を見逃してしまいます。つまり、結合が少なくなり、名前空間間でのコードの移動が容易になり、ソース コードがより簡潔で読みやすくなります。 .

多くのことと同様に、それはバランスをとる行為です。C++ 標準では、プログラマーがコード内でまったく異なるものに使用する可能性のある、 よりも「一意的」ではない多くの識別子を配置しています (例std::: 、、、、、) 。関係のない 2 つの非標準ライブラリが同じ識別子を使用する可能性ははるかに高くなります。これは、作成者が一般的に互いを認識していないか、ほとんど認識していないためです。また、ライブラリ (C++ 標準ライブラリを含む) は、時間の経過とともにシンボルを変更します。これらすべてにより、古いコードを再コンパイルするときにあいまいさが生じる可能性があります。特に、sが頻繁に使用されている場合は、coutmergeincludesfillgenerateexchangequeuetouppermaxusing namespaceusing namespace任意の大量の直接的および間接的なクライアント コードが、使用する名前空間とあいまいさを管理する方法について独自の決定を下すことができないように、ヘッダーのスコープをエスケープするためのヘッダー内の s。

したがって、リーディング::は、C++ プログラマーのツールボックスにあるツールの 1 つであり、既知の衝突を積極的に明確にし、および/または将来のあいまいさの可能性を排除します....

于 2010-11-24T16:42:45.113 に答える
45

::スコープ解決演算子です。何かの範囲を指定するために使用されます。

たとえば、::単独は、他のすべての名前空間の外側にあるグローバル スコープです。

some::thing次のいずれかの方法で解釈できます。

  • some名前空間(グローバル スコープ内、または現在のスコープよりも外側のスコープ内) でありthingtypefunctionobjectまたはネストされた namespaceです。
  • some現在のスコープで使用可能なクラスであり、クラスthingメンバー オブジェクト関数、またはですsome
  • クラス メンバー functionでは、現在の型 (または現在の型自体) の基本型someにすることができ、このクラスの 1 つのメンバー、関数、またはオブジェクトになります。thing

のように、スコープをネストすることもできますsome::thing::bad。ここで、それぞれの名前は、型、オブジェクト、または名前空間である可能性があります。さらに、最後の ,badも関数である可能性があります。関数は内部スコープ内で何も公開できないため、他の関数はできませんでした。

したがって、あなたの例に戻ると::thing、グローバルスコープ内のもの、つまり型、関数、オブジェクト、または名前空間のみになることができます。

あなたがそれを使用する方法は、それがグローバルスコープの型であることを示唆しています(ポインター宣言で使用されています)。

この回答が完全で、スコープの解決を理解するのに十分なほど正しいことを願っています。

于 2010-11-24T16:43:26.273 に答える
20

::何か (変数、関数、クラス、typedef など) を名前空間またはクラスにリンクするために使用されます。

の前に左側がない場合::は、グローバル名前空間を使用しているという事実に下線が引かれます。

例えば:

::doMyGlobalFunction();

于 2010-11-24T16:29:02.127 に答える
11

(OPはすでに彼の問題を解決しているため、この回答は主にグーグル担当者向けです。)先頭に追加され::た-スコープ結果演算子-の意味は他の回答で説明されていますが、人々がそれを使用している理由を追加したいと思います。

意味は、「グローバル名前空間から名前を取得し、それ以外のものではない」です。しかし、なぜこれを明示的に綴る必要があるのでしょうか?

ユースケース - 名前空間の衝突

グローバル名前空間とローカル/ネストされた名前空間に同じ名前がある場合、ローカルの名前が使用されます。したがって、グローバルなものが必要な場合は、先頭に::. このケースは、@Wyatt Anderson の回答で説明されています。彼の例を参照してください。

ユースケース - 非メンバー関数を強調する

メンバー関数 (メソッド) を作成する場合、他のメンバー関数の呼び出しと非メンバー (フリー) 関数の呼び出しは似ています。

class A {
   void DoSomething() {
      m_counter=0;
      ...
      Twist(data); 
      ...
      Bend(data);
      ...
      if(m_counter>0) exit(0);
   }
   int m_couner;
   ...
}

しかし、Twistが class の姉妹メンバー関数でAありBend、フリー関数である場合があります。つまり、Twist使用および変更できますがm_counerBendできません。したがって、m_counterが 0 のままであることを確認したい場合は をチェックTwistする必要がありますが、 をチェックする必要はありませんBend

したがって、これをより明確にするために、メンバー関数でthis->Twistあるリーダーを示すように書くか、フリーであることを示すように書くことができます。または両方。これは、リファクタリングを行っている、または計画しているときに非常に便利です。Twist::BendBend

于 2013-10-23T13:04:17.333 に答える
11

これはスコープ解決演算子と呼ばれます。非表示のグローバル名は、スコープ解決演算子 :: を使用して参照できます

int x;
void f2()
{
   int x = 1; // hide global x
   ::x = 2; // assign to global x
   x = 2; // assign to local x
   // ...
}
于 2013-10-11T17:59:10.767 に答える
6

::名前空間を定義する演算子です。

たとえば、using namespace std;コードで言及せずに cout を使用する場合は、次のように記述します。

std::cout << "test";

名前空間が言及されていない場合、そのクラスはグローバル名前空間に属していると言われます。

于 2010-11-24T16:26:11.757 に答える
2

"::" はスコープ解決演算子を表します。同じ名前の関数/メソッドは、2 つの異なるクラスで定義できます。特定のクラスのメソッドにアクセスするには、スコープ解決演算子が使用されます。

于 2019-02-20T17:39:05.187 に答える