prepend双冒号“::”是什么意思?
我在一个需要修改的类中找到了这行代码:
::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
,那么...
X11/xterm
...会很高兴地运行/usr/bin/X11/xterm
如果找到),否则/usr/local/bin/X11/xterm
。 同样,假设你在名为X
的名称空间中,并且有一个“ using namespace Y
”,那么......
std::cout
...可以在::X::std::cout
, ::std::cout
, ::Y::std::cout
中的任何一个中找到,并且可能在其他地方由于依赖于参数的查找(ADL,又名Koenig查找)。 所以,只有::std::cout
确切地说明了你的意思是哪个对象,但幸运的是,他们正确的头脑中没有人会创建自己的类/结构或称为“ std
”的命名空间,也没有任何称为“ cout
”的东西,所以在只使用std::cout
做法很好。
(一个值得注意的区别是,shell倾向于使用PATH
的顺序使用第一个匹配项,而C ++在出现歧义时给出编译器错误。)
关于命名空间和符号显式的一般性讨论
使用absolute ::abc::def::...
“paths”有时可以用来隔离你使用的任何其他命名空间,其中一部分但不真正控制内容,甚至是其他库您的图书馆的客户代码也使用。 另一方面,它也使您更紧密地与符号的现有“绝对”位置耦合,并且您错过了命名空间中隐式匹配的优点:耦合少,名称空间之间的代码更容易移动,以及更简洁,可读的源代码。
与许多事情一样,这是一个平衡的行为。 C ++标准在std::
中放置了很多标识符,这些标识符比cout
更“独特”,程序员可以在代码中使用完全不同的东西(例如merge
, includes
, fill
, generate
, exchange
, queue
, toupper
, max
)。 两个不相关的非标准库使用相同的标识符的可能性要高得多,因为作者通常彼此之间不太了解。 包括C ++标准库在内的库随着时间的推移而改变它们的符号。 所有这些都可能在重新编译旧代码时产生歧义,尤其是在大量使用using namespace
的情况下:在这个空间中可以做的最糟糕的事情是允许在头文件中using namespace
来转义头文件的作用域,例如任意大量的的直接和间接客户端代码无法自行决定使用哪些命名空间以及如何管理歧义。
因此,领先::
是C ++程序员工具箱中的一个工具,用于主动消除已知冲突的歧义,并且/或消除将来模糊的可能性....