[英]What is the meaning of prepended double colon "::"?
我在一個必須修改的類中找到了這行代碼:
::Configuration * tmpCo = m_configurationDB;//pointer to current db
而且我不知道類名前面的雙冒號到底是什么意思。 沒有它,我會讀到:將tmpCo
聲明為指向類Configuration
的對象的指針……但是前置的雙冒號讓我感到困惑。
我還發現:
typedef ::config::set ConfigSet;
這確保解析發生在全局命名空間,而不是從您當前所在的命名空間開始。 例如,如果您有兩個不同的類,稱為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
。
::
操作符被稱為作用域解析操作符,它就是用來解析作用域的。 因此,通過在類型名稱前面加上前綴,它會告訴您的編譯器在全局命名空間中查找該類型。
例子:
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;
}
已經有很多合理的答案了。 我會用一個類比來幫助一些讀者。 ::
在搜索路徑以查找要運行的程序時,它的工作方式與文件系統目錄分隔符“ /
”非常相似。 考慮:
/path/to/executable
這是非常明確的——只有在文件系統樹中那個確切位置的可執行文件才能匹配這個規范,而不管 PATH 是否有效。 相似地...
::std::cout
...在 C++ 命名空間“樹”中同樣明確。
與這種絕對路徑相比,您可以配置好的 UNIX shell(例如zsh )來解析當前目錄下的相對路徑或PATH
環境變量中的任何元素,因此如果PATH=/usr/bin:/usr/local/bin
,以及你“在” /tmp
,然后......
X11/xterm
...如果找到,會很樂意運行/tmp/X11/xterm
,否則/usr/bin/X11/xterm
,否則/usr/local/bin/X11/xterm
。 類似地,假設您在一個名為X
的命名空間中,並且有效地using namespace Y
了“ using namespace Y
”,那么...
std::cout
...可以在::X::std::cout
、 ::std::cout
、 ::Y::std::cout
中的任何一個中找到,並且可能由於參數相關的查找(ADL,又名柯尼格查找)。 因此,只有::std::cout
真正明確地說明了您指的是哪個對象,但幸運的是,沒有人會創建自己的類/結構或名為“ std
”的名稱空間,也不會創建任何名為“ cout
”的東西,所以在練習只使用std::cout
很好。
值得注意的區別:
1) shell 傾向於使用PATH
的排序使用第一個匹配項,而 C++ 在您有歧義時會給出編譯器錯誤。
2) 在 C++ 中,可以在當前命名空間中匹配沒有任何前導作用域的名稱,而大多數 UNIX shell 僅在將.
在PATH
。
3)C++ 總是搜索全局命名空間(比如有/
隱式你的PATH
)。
使用絕對::abc::def::...
"paths" 有時有助於將您與您正在使用的任何其他名稱空間隔離開來,部分但實際上無法控制其內容,甚至其他庫您圖書館的客戶端代碼也使用。 另一方面,它也將您更緊密地耦合到符號的現有“絕對”位置,並且您錯過了命名空間中隱式匹配的優點:更少的耦合、更容易在命名空間之間的代碼移動性以及更簡潔、可讀的源代碼.
與許多事情一樣,這是一種平衡行為。 C++ 標准在std::
下放置了許多標識符,它們比cout
更不“獨特”,程序員可能會將它們用於代碼中完全不同的東西(例如merge
、 includes
、 fill
、 generate
、 exchange
、 queue
、 toupper
、 max
)。 兩個不相關的非標准庫使用相同標識符的可能性要高得多,因為作者通常不知道或不太了解彼此。 和庫 - 包括 C++ 標准庫 - 隨着時間的推移改變它們的符號。 所有這些都可能在重新編譯舊代碼時產生歧義,特別是當大量使用using namespace
s 時:在這個空間中你能做的最糟糕的事情是允許在頭文件中using namespace
s 來逃避頭文件的范圍,這樣任意大的數量的直接和間接客戶端代碼無法自己決定使用哪些名稱空間以及如何管理歧義。
因此,領先的::
是 C++ 程序員工具箱中的一種工具,可以主動消除已知沖突的歧義,和/或消除未來歧義的可能性......
::
是范圍解析運算符。 它用於指定某物的范圍。
例如, ::
單獨是全局范圍,在所有其他名稱空間之外。
some::thing
可以用以下任何一種方式解釋:
some
是一個命名空間(在全局范圍內,或比當前范圍更遠的范圍內),而thing
是一個類型、一個函數、一個對象或一個嵌套的命名空間;some
是當前作用域中可用的類, thing
是some
類的成員對象、函數或類型;some
可以是當前類型(或當前類型本身)的基類型,然后thing
是此類的一個成員,類型,函數或對象。 你也可以有嵌套作用域,如some::thing::bad
。 這里的每個名稱都可以是一個類型、一個對象或一個命名空間。 此外,最后一個bad
也可能是一個函數。 其他人不能,因為函數不能在其內部范圍內公開任何內容。
所以,回到你的例子, ::thing
只能是全局范圍內的東西:類型、函數、對象或命名空間。
您使用它的方式表明(在指針聲明中使用)它是全局范圍內的類型。
我希望這個答案足夠完整和正確,以幫助您了解示波器分辨率。
::
用於將某些東西(變量、函數、類、typedef 等)鏈接到命名空間或類。
如果::
之前沒有左側,那么它強調了您正在使用全局命名空間的事實。
例如:
::doMyGlobalFunction();
它稱為范圍解析運算符,可以使用范圍解析運算符 :: 引用隱藏的全局名稱
例如;
int x;
void f2()
{
int x = 1; // hide global x
::x = 2; // assign to global x
x = 2; // assign to local x
// ...
}
(這個答案主要是針對谷歌人的,因為 OP 已經解決了他的問題。)前置::
的含義 - 范圍結果運算符 - 已在其他答案中進行了描述,但我想補充一下人們使用它的原因。
意思是“從全局命名空間中取名,而不是其他任何東西”。 但是為什么需要明確拼寫呢?
用例 - 命名空間沖突
當您在全局命名空間和本地/嵌套命名空間中具有相同的名稱時,將使用本地名稱。 所以如果你想要全局的,在它前面加上::
。 這個案例在@Wyatt Anderson 的回答中有描述,請看他的例子。
用例——強調非成員函數
在編寫成員函數(方法)時,對其他成員函數的調用和對非成員(自由)函數的調用看起來很相似:
class A {
void DoSomething() {
m_counter=0;
...
Twist(data);
...
Bend(data);
...
if(m_counter>0) exit(0);
}
int m_couner;
...
}
但也有可能Twist
是A
類的姐妹成員函數,而Bend
是自由函數。 也就是說, Twist
可以使用和修改m_couner
而Bend
不能。 所以如果你想確保m_counter
保持為 0,你必須檢查Twist
,但你不需要檢查Bend
。
因此,為了更清楚地突出這一點,您可以編寫this->Twist
來向讀者表明Twist
是一個成員函數,或者編寫::Bend
來表明Bend
是自由的。 或兩者。 這在您進行或計划重構時非常有用。
::
是定義命名空間的運算符。
例如,如果您想使用 cout 而不提及using namespace std;
在你的代碼中你這樣寫:
std::cout << "test";
當沒有提到命名空間時,就說這個類屬於全局命名空間。
“::”代表作用域解析運算符。 具有相同名稱的函數/方法可以定義在兩個不同的類中。 訪問特定類范圍解析運算符的方法被使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.