C++ 前置双冒号“::”是什么意思?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4269034/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the meaning of prepended double colon "::"?
提问by rmbianchi
I found this line of a code in a class which I have to modify:
我在一个必须修改的类中找到了这行代码:
::Configuration * tmpCo = m_configurationDB;//pointer to current db
and I don't know what exactly means the double colon prepended to the class name. Without that I would read: declaration of tmpCo
as a pointer to an object of the class Configuration
... but the prepended double colon confuses me.
而且我不知道类名前面的双冒号到底是什么意思。没有它,我会读到:tmpCo
作为指向类对象的指针的声明Configuration
......但是前置的双冒号让我感到困惑。
I also found:
我还发现:
typedef ::config::set ConfigSet;
回答by Wyatt Anderson
This ensures that resolution occurs from the global namespace, instead of starting at the namespace you're currently in. For instance, if you had two different classes called Configuration
as such:
这确保解析发生在全局命名空间,而不是从您当前所在的命名空间开始。例如,如果您有两个不同的类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(...)
}
}
Basically, it allows you to traverse up to the global namespace since your name might get clobbered by a new definition inside another namespace, in this case MyApp
.
基本上,它允许您遍历全局名称空间,因为您的名称可能会被另一个名称空间内的新定义破坏,在这种情况下MyApp
。
回答by Moo-Juice
The ::
operator is called the scope-resolution operator and does just that, it resolves scope. So, by prefixing a type-name with this, it tells your compiler to look in the global namespace for the type.
该::
操作被称为范围分辨率运营商,做到了这一点,它解决的范围。因此,通过在类型名称前面加上前缀,它会告诉您的编译器在全局命名空间中查找该类型。
Example:
例子:
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;
}
回答by Tony Delroy
Lots of reasonable answers already. I'll chip in with an analogy that may help some readers. ::
works a lot like the filesystem directory separator '/
', when searching your path for a program you'd like to run. Consider:
已经有很多合理的答案了。我会用一个类比来帮助一些读者。 在搜索路径以查找要运行的程序时,::
其工作方式与文件系统目录分隔符“ /
”非常相似。考虑:
/path/to/executable
This is very explicit - only an executable at that exact location in the filesystem tree can match this specification, irrespective of the PATH in effect. Similarly...
这是非常明确的——只有在文件系统树中那个确切位置的可执行文件才能匹配这个规范,而不管 PATH 是否有效。相似地...
::std::cout
...is equally explicit in the C++ namespace "tree".
...在 C++ 命名空间“树”中同样明确。
Contrasting with such absolute paths, you can configure good UNIX shells (e.g. zsh) to resolve relativepaths under your current directory or any element in your PATH
environment variable, so if PATH=/usr/bin:/usr/local/bin
, and you were "in" /tmp
, then...
与这种绝对路径相比,您可以配置好的 UNIX shell(例如zsh)来解析当前目录下的相对路径或PATH
环境变量中的任何元素,因此,如果PATH=/usr/bin:/usr/local/bin
, 并且您“在”中/tmp
,那么...
X11/xterm
...would happily run /tmp/X11/xterm
if found, else /usr/bin/X11/xterm
, else /usr/local/bin/X11/xterm
. Similarly, say you were in a namespace called X
, and had a "using namespace Y
" in effect, then...
.../tmp/X11/xterm
如果找到,会很高兴地运行,否则/usr/bin/X11/xterm
,否则/usr/local/bin/X11/xterm
。类似地,假设您在一个名为 的命名空间中X
,并且实际上有一个“ using namespace Y
”,那么...
std::cout
...could be found in any of ::X::std::cout
, ::std::cout
, ::Y::std::cout
, and possibly other places due to argument-dependent lookup(ADL, aka Koenig lookup). So, only ::std::cout
is really explicit about exactly which object you mean, but luckily nobody in their right mind would ever create their own class/struct or namespace called "std
", nor anything called "cout
", so in practice using only std::cout
is fine.
...可以在任何的发现::X::std::cout
,::std::cout
,::Y::std::cout
,和其他可能的地方由于参数相关查找(ADL,又称Koenig查找)。所以, only::std::cout
确实明确了你的意思到底是哪个对象,但幸运的是,没有人会创建自己的类/结构或命名空间,称为“ std
”,也没有任何称为“ cout
”的东西,所以在实践中使用 onlystd::cout
是可以的。
Noteworthy differences:
值得注意的区别:
1) shells tend to use the first match using the ordering in PATH
, whereas C++ gives a compiler error when you've been ambiguous.
1) shells 倾向于使用第一个匹配使用 in 中的排序PATH
,而 C++ 会在您有歧义时给出编译器错误。
2) In C++, names without any leading scope can be matched in the current namespace, while most UNIX shells only do that if you put .
in the PATH
.
2) 在 C++ 中,可以在当前命名空间中匹配没有任何前导作用域的名称,而大多数 UNIX shell 仅.
在将PATH
.
3) C++ always searches the global namespace (like having /
implicitly your PATH
).
3) C++ 总是搜索全局命名空间(就像/
隐式地你的PATH
)。
General discussion on namespaces and explicitness of symbols
关于名称空间和符号显式性的一般讨论
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.
使用绝对::abc::def::...
“路径”有时有助于将您与您正在使用的任何其他名称空间隔离开来,部分但实际上无法控制其内容,甚至是您的库的客户端代码也使用的其他库。另一方面,它也将您更紧密地耦合到符号的现有“绝对”位置,并且您错过了命名空间中隐式匹配的优点:更少的耦合、更容易在命名空间之间的代码移动性以及更简洁、可读的源代码.
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 namespace
s: the worst thing you can do in this space is allow using namespace
s 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++ 标准在std::
其下放置了许多标识符,它们的“唯一性”不如cout
,程序员可能会将其用于代码中完全不同的事物(例如merge
, includes
, fill
, generate
, exchange
, queue
, toupper
, max
)。两个不相关的非标准库使用相同标识符的可能性要高得多,因为作者通常不知道或不太了解彼此。和库 - 包括 C++ 标准库 - 随着时间的推移改变它们的符号。所有这些都可能在重新编译旧代码时产生歧义,尤其是在大量使用using namespace
s 时:在这个空间中你能做的最糟糕的事情是允许using namespace
s 在标头中以逃避标头的范围,这样任意大量的直接和间接客户端代码无法自己决定使用哪些名称空间以及如何管理歧义。
So, a leading ::
is one tool in the C++ programmer's toolbox to actively disambiguate a known clash, and/or eliminate the possibility of future ambiguity....
因此,领先::
是 C++ 程序员工具箱中的一种工具,可以主动消除已知冲突的歧义,和/或消除未来歧义的可能性......
回答by Klaim
::
is the scope resolution operator. It's used to specify the scope of something.
::
是范围解析运算符。它用于指定某物的范围。
For example, ::
alone is the global scope, outside all other namespaces.
例如,::
在所有其他命名空间之外,只有全局作用域。
some::thing
can be interpreted in any of the following ways:
some::thing
可以用以下任何一种方式来解释:
some
is a namespace(in the global scope, or an outer scope than the current one) andthing
is a type, a function, an objector a nested namespace;some
is a classavailable in the current scope andthing
is a member object, functionor typeof thesome
class;- in a class member function,
some
can be a base typeof the current type (or the current type itself) andthing
is then one member of this class, a type, functionor object.
some
是一个命名空间(在全局范围内,或比当前范围更远的范围内)并且thing
是一个类型、一个函数、一个对象或一个嵌套的命名空间;some
是一个类在当前范围内可用的并且thing
是一个成员对象,功能或类型的的some
类;- 在类成员函数中,
some
可以是当前类型(或当前类型本身)的基类型,thing
然后是此类的一个成员,类型,函数或对象。
You can also have nested scope, as in some::thing::bad
. Here each name could be a type, an object or a namespace. In addition, the last one, bad
, could also be a function. The others could not, since functions can't expose anything within their internal scope.
您还可以具有嵌套作用域,如some::thing::bad
. 这里的每个名称都可以是一个类型、一个对象或一个命名空间。此外,最后一个 ,bad
也可以是一个函数。其他人不能,因为函数不能在其内部范围内公开任何内容。
So, back to your example, ::thing
can be only something in the global scope: a type, a function, an object or a namespace.
因此,回到您的示例,::thing
只能是全局范围内的某些内容:类型、函数、对象或命名空间。
The way you use it suggests (used in a pointer declaration) that it's a type in the global scope.
您使用它的方式表明(在指针声明中使用)它是全局范围内的类型。
I hope this answer is complete and correct enough to help you understand scope resolution.
我希望这个答案足够完整和正确,以帮助您了解示波器分辨率。
回答by Stephane Rolland
::
is used to link something ( a variable, a function, a class, a typedef etc...) to a namespace, or to a class.
::
用于将某些东西(变量、函数、类、typedef 等)链接到命名空间或类。
if there is no left hand side before ::
, then it underlines the fact you are using the global namespace.
如果之前没有左侧::
,那么它强调了您正在使用全局命名空间的事实。
e.g.:
例如:
::doMyGlobalFunction();
::doMyGlobalFunction();
回答by Mustafa Ekici
its called scope resolution operator, A hidden global name can be referred to using the scope resolution operator ::
For example;
它称为作用域解析运算符,可以使用作用域解析运算符 :: 引用隐藏的全局名称:
例如;
int x;
void f2()
{
int x = 1; // hide global x
::x = 2; // assign to global x
x = 2; // assign to local x
// ...
}
回答by Steed
(This answer is mostly for googlers, because OP has solved his problem already.)
The meaning of prepended ::
- scope resulution operator - has been described in other answers, but I'd like to add why people are using it.
(这个答案主要是针对谷歌员工的,因为 OP 已经解决了他的问题。)::
其他答案中已经描述了前置- 范围结果运算符 -的含义,但我想补充一下人们使用它的原因。
The meaning is "take name from global namespace, not anything else". But why would this need to be spelled explicitly?
意思是“从全局命名空间中取名,而不是其他任何东西”。但是为什么需要明确拼写呢?
Use case - namespace clash
用例 - 命名空间冲突
When you have the same name in global namespace and in local/nested namespace, the local one will be used. So if you want the global one, prepend it with ::
. This case was described in @Wyatt Anderson's answer, plese see his example.
当您在全局命名空间和本地/嵌套命名空间中具有相同名称时,将使用本地名称。所以如果你想要全局的,在它前面加上::
. 这个案例在@Wyatt Anderson 的回答中有描述,请看他的例子。
Use case - emphasise non-member function
用例——强调非成员函数
When you are writing a member function (a method), calls to other member function and calls to non-member (free) functions look alike:
在编写成员函数(方法)时,对其他成员函数的调用和对非成员(自由)函数的调用看起来很相似:
class A {
void DoSomething() {
m_counter=0;
...
Twist(data);
...
Bend(data);
...
if(m_counter>0) exit(0);
}
int m_couner;
...
}
But it might happen that Twist
is a sister member function of class A
, and Bend
is a free function. That is, Twist
can use and modify m_couner
and Bend
cannot. So if you want to ensure that m_counter
remains 0, you have to check Twist
, but you don't need to check Bend
.
但也有可能它Twist
是 class 的姐妹成员函数A
,并且Bend
是一个自由函数。也就是说,Twist
可以使用和修改m_couner
,Bend
不能。因此,如果您想确保m_counter
仍然为 0,则必须检查Twist
,但不需要检查Bend
。
So to make this stand out more clearly, one can either write this->Twist
to show the reader that Twist
is a member function or write ::Bend
to show that Bend
is free. Or both. This is very useful when you are doing or planning a refactoring.
因此,为了更清楚地突出这一点,您可以编写this->Twist
以向读者展示它Twist
是一个成员函数,或者编写::Bend
以表明它Bend
是免费的。或两者。这在您进行或计划重构时非常有用。
回答by Vladimir Ivanov
::
is a operator of defining the namespace.
::
是定义命名空间的运算符。
For example, if you want to use cout without mentioning using namespace std;
in your code you write this:
例如,如果您想using namespace std;
在代码中不提及而使用 cout ,您可以这样写:
std::cout << "test";
When no namespace is mentioned, that it is said that class belongs to global namespace.
当没有提到命名空间时,就说这个类属于全局命名空间。
回答by Vaman Acharya
"::" represents scope resolution operator. Functions/methods which have same name can be defined in two different classes. To access the methods of a particular class scope resolution operator is used.
“::”代表作用域解析运算符。具有相同名称的函数/方法可以定义在两个不同的类中。访问特定类范围解析运算符的方法被使用。