关于c ++:为什么::(范围)与空的左操作数一起使用?

Why is :: (scope) used with empty left-hand operand?

本问题已经有最佳答案,请猛点这里访问。

我已经看过几次了,我一直在挠头,想知道为什么……

例如:(http://www.codeguru.com/forum/showthread.php)t=377394)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void LeftClick ( )
{  
  INPUT    Input={0};
  // left down
  Input.type      = INPUT_MOUSE;
  Input.mi.dwFlags  = MOUSEEVENTF_LEFTDOWN;
  ::SendInput(1,&Input,sizeof(INPUT));

  // left up
  ::ZeroMemory(&Input,sizeof(INPUT));
  Input.type      = INPUT_MOUSE;
  Input.mi.dwFlags  = MOUSEEVENTF_LEFTUP;
  ::SendInput(1,&Input,sizeof(INPUT));
}

这个例子不使用::(scope)操作符,那么为什么它们甚至在那里呢?


这基本上意味着"获取全局范围的函数,而不是当前可见的函数"。

1
2
3
4
5
6
7
8
9
10
11
12
13
void SendInput() { /* (1) */
}

namespace derp {
    void SendInput() { /* (2) */
    }

    void LeftClick() {
        ...
        ::SendInput(); /* matches (1) */
        SendInput();  /* matches (2) */
    }
}


假设您有以下内容:

1
2
3
4
5
6
7
8
void bar()
{
}

struct Foo
{
    void bar();
};

如果要从成员函数Foo::bar调用全局函数bar,请使用左侧为空的语法:

1
2
3
4
5
void Foo::bar()
{
    // Call the global bar function, not recursively call myself
    ::bar();
}


它强制绝对名称解析。如果没有它,将搜索与类/函数命名空间路径相关的名称解析。

因此假设leftclick()位于命名空间层次结构中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace Level1
{
    namespace Level2
    {
        namespace Level3
        {
            LeftClick()
            {
                 ::SendInput();   // Absolute path only. SendInput in global namespace
                 SendInput();     // Relative path (Note resolved at compile time)
                                  //
                                  // Looks for the function here (in this order)
                                  //    ::Level1::Level2::Level3::SendInput()
                                  //    ::Level1::Level2::SendInput()
                                  //    ::Level1::SendInput()
                                  //    ::SendInput()
            }
        }
    }
}

如果您有一个嵌套的名称,它会变得更有趣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
namespace Level1
{
    namespace Level2
    {
        namespace Level3
        {
            LeftClick()
            {
                 ::Test::Action();  // Absolute Path: Function Action()
                                    //                in namespace Test
                                    //                in global namespace

                 Test::Action();    // Relative Path: Function Action()
                                    //                in namespace Test
                                    //                in current namespace path.
                                    //
                     // It will Look for Test (in this order)
                     // ::Level1::Level2::Level3::Test
                     // ::Level1::Level2::Test
                     // ::Level1::Test
                     // ::Test
                     //
                     // In the first Test (and only the first) it finds it will
                     // try and resolve the Action() function. If it is not there
                     // it is a compile time error.
            }
        }
    }
}

它将强制符号在全局范围内被查找。

1
2
3
4
5
6
7
8
9
10
11
12
void foo() {} // 1

namespace A
{
    void foo() {} // 2

    void bar()
    {
        foo(); // 2
        ::foo(); // 1
    }
}

::用于直接从对象外部访问对象。


以这种方式使用范围运算符意味着您指的是全局范围。

为了节省宝贵的时间和击键,请查看不带范围的范围解析操作符。