为啥 :: (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) 与空的左操作数一起使用? [复制]的主要内容,如果未能解决你的问题,请参考以下文章