为啥 :: (scope) 与空的左操作数一起使用? [复制]

Posted

技术标签:

【中文标题】为啥 :: (scope) 与空的左操作数一起使用? [复制]【英文标题】:Why is :: (scope) used with empty left-hand operand? [duplicate]为什么 :: (scope) 与空的左操作数一起使用? [复制] 【发布时间】:2012-01-30 13:20:39 【问题描述】:

我已经看过几次了,我一直在摸不着头脑想知道为什么......

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

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));

这个例子在没有 ::(范围)操作符的情况下也能工作,那么为什么它们还在那里呢?

【问题讨论】:

如果 // left down 被删除,它也可以工作。那么它为什么会存在呢?为了清楚起见。 假设 OP 是正确的,即使没有 ::,它也能“工作”,那么是的,真的。但我知道还有更多内容,这就是我没有发布答案的原因。 常用在Windows中,MFC类往往有与全局API函数同名的成员函数。使用 :: 告诉我们您确实打算调用 API 函数。 是吗?我从来没有在 Windows 中进行过太多编程。在我看来,另一件事我可以忘记并搞砸一些事情:-) 由于我无法编辑之前对 tenfour 的评论,我的意图是通过添加无用的::,您的代码会变得更加混乱,而不是更加清晰。 【参考方案1】:

这基本上意味着“获取 GLOBAL 范围的函数,而不是当前可见的函数”。

void SendInput()  /* (1) */


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

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

【讨论】:

在这种情况下(它意味着全局)。它实际上意味着使用“绝对命名空间路径”而不是“相对命名空间路径”。在这种情况下,它恰好是一条短路径,因此在全局命名空间中。 @LokiAstari 你能详细说明区别吗?它与将文件称为/path/to/file.txt 而不是./path/to/file.txt 基本相同吗?一个是相对于当前位置,另一个是相对于特定位置? (在本例中为根文件夹) @QPaysTaxes:一个很好的类比。但是您还需要应用 PATH 变量来使模拟效果更好。将在路径中的每个目录中搜索相对路径(而绝对路径不会)。在 C++ 情况下,PATH 由当前位置的每个嵌套范围表示。请参阅gist.github.com/Loki-Astari/bddbdc98e8c8b9da5edc 这使得实际路径容易受到添加到父命名空间中的新代码的影响。 与类一起使用时效果一样吗? class Test : public ::OtherClass 是@Winter(一些字符)【参考方案2】:

假设您有以下内容:

void bar()



struct Foo

    void bar();
;

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

void Foo::bar()

    // Call the global bar function, not recursively call myself
    ::bar();

【讨论】:

【参考方案3】:

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

所以假设 LeftClick() 在命名空间层次结构中:

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()
            
        
    

如果你有一个嵌套的名字会变得更有趣:

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.
            
        
    

【讨论】:

【参考方案4】:

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

void foo()  // 1

namespace A

    void foo()  // 2

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

【讨论】:

【参考方案5】:

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

为了节省我宝贵的时间和击键次数,请查看scope resolution operator without a scope。

【讨论】:

【参考方案6】:

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

【讨论】:

以上是关于为啥 :: (scope) 与空的左操作数一起使用? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

读取Cookie时总是空的,为啥

为啥在返回值之前将字符串与空值连接?

如何在 MySQL 5.7 中将 WHERE IN 与空值一起使用?

为啥与空列表连接时返回列表但与新列表连接时不返回?

为啥我的 ComboBox 是空的,尽管变量已初始化?

(null) <null> 与空 及其字符串的判断