在 C++ 中使用 ::

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15649580/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:35:48  来源:igfitidea点击:

Using :: in C++

c++functionnamespaces

提问by foobar5512

I am learning C++ and I can never tell when I need to use ::. I do know that I need to use std::in front of coutand cin. Does this mean that inside of the iostreamfile the developers that created it made a namespace called stdand put the functions cinand coutinto the namespace called std? When I created a new class that isn't in the same file as main()for some reason I must add ::.

我正在学习 C++,我永远不知道什么时候需要使用::. 我知道我需要std::coutand前面使用cin。这是否意味着,该内部iostream文件创建它做了一个叫做命名空间的开发std,并把功能cincout进入所谓的命名空间std?当我创建一个新类时,由于main()某种原因,它不在同一个文件中,我必须添加::.

For example, if I create a classcalled A, why do I need to put A::in front of a function that I make, even though I didn't put it into a namesace? For example void A::printStuff(){}. If I create a function in main, why don't I have to put main::printStuf{}?

例如,如果我创建了一个class被调用的A,为什么我需要把它放在我创建的A::函数前面,即使我没有把它放在一个命名中?例如void A::printStuff(){}。如果我在 中创建一个函数main,为什么我不必放置main::printStuf{}

I know that my question is probably confusing, but could someone help me?

我知道我的问题可能令人困惑,但有人可以帮助我吗?

回答by Joseph Mansfield

You're pretty much right about coutand cin. They are objects (not functions) defined inside the stdnamespace. Here are their declarations as defined by the C++ standard:

你说的对coutcin。它们是在std命名空间内定义的对象(不是函数)。以下是 C++ 标准定义的它们的声明:

Header <iostream>synopsis

#include <ios>
#include <streambuf>
#include <istream>
#include <ostream>

namespace std {
  extern istream cin;
  extern ostream cout;
  extern ostream cerr;
  extern ostream clog;

  extern wistream wcin;
  extern wostream wcout;
  extern wostream wcerr;
  extern wostream wclog;
}

标题<iostream>概要

#include <ios>
#include <streambuf>
#include <istream>
#include <ostream>

namespace std {
  extern istream cin;
  extern ostream cout;
  extern ostream cerr;
  extern ostream clog;

  extern wistream wcin;
  extern wostream wcout;
  extern wostream wcerr;
  extern wostream wclog;
}

::is known as the scope resolution operator. The names coutand cinare defined within std, so we have to qualify their names with std::.

::被称为范围解析运算符。名称coutcin是在 内定义的std,因此我们必须用 限定它们的名称std::

Classes behave a little like namespaces in that the names declared inside the class belong to the class. For example:

类的行为有点像命名空间,因为在类内部声明的名称属于该类。例如:

class foo
{
  public:
    foo();
    void bar();
};

The constructor named foois a memberof the class named foo. They have the same name because its the constructor. The function baris also a member of foo.

命名的构造函数foo是名为 的类的成员foo。它们具有相同的名称,因为它是构造函数。该函数bar也是 的成员foo

Because they are members of foo, when referring to them from outside the class, we have to qualify their names. After all, they belong to that class. So if you're going to define the constructor and baroutside the class, you need to do it like so:

因为他们是 的成员foo,所以当从类外引用他们时,我们必须限定他们的名字。毕竟,他们属于那个阶级。因此,如果您要bar在类之外定义构造函数,则需要这样做:

foo::foo()
{
  // Implement the constructor
}

void foo::bar()
{
  // Implement bar
}

This is because they are being defined outsidethe class. If you had not put the foo::qualification on the names, you would be defining some new functions in the global scope, rather than as members of foo. For example, this is entirely different bar:

这是因为它们是在类之外定义的。如果您没有foo::对名称进行限定,那么您将在全局范围内定义一些新函数,而不是作为foo. 例如,这是完全不同的bar

void bar()
{
  // Implement different bar
}

It's allowed to have the same name as the function in the fooclass because it's in a different scope. This baris in the global scope, whereas the other barbelonged to the fooclass.

允许与foo类中的函数具有相同的名称,因为它在不同的范围内。这bar是在全局范围内,而另一个bar属于foo类。

回答by scones

The ::are used to dereference scopes.

::用于取消引用范围。

const int x = 5;

namespace foo {
  const int x = 0;
}

int bar() {
  int x = 1;
  return x;
}

struct Meh {
  static const int x = 2;
}

int main() {
  std::cout << x; // => 5
  {
    int x = 4;
    std::cout << x; // => 4
    std::cout << ::x; // => 5, this one looks for x outside the current scope
  }
  std::cout << Meh::x; // => 2, use the definition of x inside the scope of Meh
  std::cout << foo::x; // => 0, use the definition of x inside foo
  std::cout << bar(); // => 1, use the definition of x inside bar (returned by bar)
}

unrelated: cout and cin are not functions, but instances of stream objects.

无关: cout 和 cin 不是函数,而是流对象的实例。

EDITfixed as Keine Lustsuggested

编辑修复了Keine Lust 的建议

回答by Johnny Mnemonic

The ::is called scope resolution operator. Can be used like this:

::被称为作用域解析运算符。可以这样使用:

::identifier
class-name::identifier
namespace::identifier

::标识符
类名::标识符
命名空间::标识符

You can read about it here
https://docs.microsoft.com/en-us/cpp/cpp/scope-resolution-operator?view=vs-2017

你可以在这里阅读它
https://docs.microsoft.com/en-us/cpp/cpp/scope-resolution-operator?view=vs-2017

回答by TrevorLee

One use for the 'Unary Scope Resolution Operator' or 'Colon Colon Operator' is for local and global variable selection of identical names:

“一元范围解析运算符”或“冒号冒号运算符”的一种用途是用于相同名称的局部和全局变量选择:

    #include <iostream>
    using namespace std;

    int variable = 20;

    int main()
    {
    float variable = 30;

    cout << "This is local to the main function: " << variable << endl;
    cout << "This is global to the main function: " << ::variable << endl;

    return 0;
    }

The resulting output would be:

结果输出将是:

This is local to the main function: 30

This is global to the main function: 20

这是主要功能的本地:30

这是主要功能的全局:20

Other uses could be: Defining a function from outside of a class, to access a static variable within a class or to use multiple inheritance.

其他用途可能是:从类外部定义函数、访问类内的静态变量或使用多重继承。

回答by vincent87

look at it is informative [Qualified identifiers

看看它是信息性的 [合格标识符

A qualified id-expression is an unqualified id-expression prepended by a scope resolution operator ::, and optionally, a sequence of enumeration, (since C++11)class or namespace names or decltype expressions (since C++11) separated by scope resolution operators. For example, the expression std::string::npos is an expression that names the static member npos in the class string in namespace std. The expression ::tolower names the function tolower in the global namespace. The expression ::std::cout names the global variable cout in namespace std, which is a top-level namespace. The expression boost::signals2::connection names the type connection declared in namespace signals2, which is declared in namespace boost.

限定的 id 表达式是由作用域解析运算符 :: 和可选的枚举序列、(C++11 起)类或命名空间名称或 decltype 表达式(C++11 起)分隔的非限定 id 表达式通过范围解析运算符。例如,表达式 std::string::npos 是命名空间 std 中类字符串中的静态成员 npos 的表达式。表达式 ::tolower 将全局命名空间中的函数命名为 tolower。表达式 ::std::cout 将命名空间 std 中的全局变量 cout 命名为顶级命名空间。表达式 boost::signals2::connection 命名在名称空间 signal2 中声明的类型连接,它在名称空间 boost 中声明。

The keyword template may appear in qualified identifiers as necessary to disambiguate dependent template names]1

关键字模板可以根据需要出现在限定标识符中,以消除相关模板名称的歧义] 1