我在一个类中发现了这一行代码,我必须修改:
::Configuration * tmpCo = m_configurationDB;//pointer to current db
我不知道类名前的双冒号是什么意思。如果没有,我会读到:声明tmpCo作为类Configuration对象的指针…但是前面的双冒号把我弄糊涂了。
我还发现:
typedef ::config::set ConfigSet;
我在一个类中发现了这一行代码,我必须修改:
::Configuration * tmpCo = m_configurationDB;//pointer to current db
我不知道类名前的双冒号是什么意思。如果没有,我会读到:声明tmpCo作为类Configuration对象的指针…但是前面的双冒号把我弄糊涂了。
我还发现:
typedef ::config::set ConfigSet;
当前回答
::用于将某些东西(变量、函数、类、类型定义等)链接到名称空间或类。
如果在::之前没有左边,那么它强调了您正在使用全局名称空间的事实。
例如:
::d oMyGlobalFunction();
其他回答
已经有很多合理的答案了。我将插进一个比喻,可能会帮助一些读者。::工作起来很像文件系统目录分隔符'/',当你搜索你想要运行的程序时。考虑:
/path/to/executable
这是非常显式的——只有位于文件系统树中确切位置的可执行文件才能匹配此规范,而不考虑实际的PATH。同样……
::std::cout
...在c++命名空间“tree”中同样显式。
与这些绝对路径相比,你可以配置好的UNIX shell(例如zsh)来解析当前目录下的相对路径或PATH环境变量中的任何元素,因此如果PATH=/usr/bin:/usr/local/bin,并且你在/tmp中,那么…
X11/xterm
...如果找到/tmp/X11/xterm, else /usr/bin/X11/xterm, else /usr/local/bin/X11/xterm类似地,假设您在一个名为X的名称空间中,并且“正在使用名称空间Y”,那么……
std::cout
…可以在::X::std::cout,::std::cout,::Y::std::cout中的任何地方找到,并且可能由于依赖参数的查找(ADL,又名Koenig查找)而在其他地方找到。因此,only::std::cout真正明确了你指的是哪个对象,但幸运的是,没有哪个头脑正常的人会创建自己的类/结构或命名空间称为“std”,也不会创建任何名为“cout”的东西,所以在实践中只使用std::cout是可以的。
值得注意的差异:
1) shell倾向于使用PATH中的顺序来使用第一个匹配,而c++在你有歧义的时候会给出编译器错误。
2)在c++中,没有任何前导作用域的名称可以在当前命名空间中匹配,而大多数UNIX shell只在您放置。在PATH中。
3) c++总是搜索全局命名空间(就像/隐式地拥有你的PATH)。
关于命名空间和符号的显式性的一般性讨论
Using absolute ::abc::def::... "paths" can sometimes be useful to isolate you from any other namespaces you're using, part of but don't really have control over the content of, or even other libraries that your library's client code also uses. On the other hand, it also couples you more tightly to the existing "absolute" location of the symbol, and you miss the advantages of implicit matching in namespaces: less coupling, easier mobility of code between namespaces, and more concise, readable source code.
As with many things, it's a balancing act. The C++ Standard puts lots of identifiers under std:: that are less "unique" than cout, that programmers might use for something completely different in their code (e.g. merge, includes, fill, generate, exchange, queue, toupper, max). Two unrelated non-Standard libraries have a far higher chance of using the same identifiers as the authors are generally un- or less-aware of each other. And libraries - including the C++ Standard library - change their symbols over time. All this potentially creates ambiguity when recompiling old code, particularly when there's been heavy use of using namespaces: the worst thing you can do in this space is allow using namespaces in headers to escape the headers' scopes, such that an arbitrarily large amount of direct and indirect client code is unable to make their own decisions about which namespaces to use and how to manage ambiguities.
因此,前导::是c++程序员工具箱中的一个工具,用于主动消除已知冲突的歧义,和/或消除未来歧义的可能性....
一个隐藏的全局名称可以使用作用域解析操作符引用:: 例如;
int x;
void f2()
{
int x = 1; // hide global x
::x = 2; // assign to global x
x = 2; // assign to local x
// ...
}
这确保解析是从全局名称空间进行的,而不是从您当前所在的名称空间开始。例如,如果你有两个不同的类叫做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)中的新定义所破坏。
::用于将某些东西(变量、函数、类、类型定义等)链接到名称空间或类。
如果在::之前没有左边,那么它强调了您正在使用全局名称空间的事实。
例如:
::d oMyGlobalFunction();
"::"表示范围解析运算符。 具有相同名称的函数/方法可以定义在两个不同的类中。要访问特定类的方法,使用范围解析运算符。