2011-12-30 2 views
9

Я видел это несколько раз сейчас, и я почесывал голову, задаваясь вопросом, почему ...Почему :: (область) используется с пустым левым операндом?

В качестве примера: (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)); 
} 

Этот пример работает без операторов :: (scope), так почему они вообще существуют?

+0

Это также работает, если '// левый down' является удален. Так почему это так? Для ясности. – tenfour

+0

@tenfour Не совсем ... –

+0

Предполагая, что OP правильно, что он «работает» даже без '::', то да, действительно. Но я понимаю, что это еще не все, и именно поэтому я не публиковал ответ. – tenfour

ответ

22

Это в основном означает «получить функцию GLOBAL scoped, а не видимую в данный момент».

void SendInput() { /* (1) */ 
} 

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

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

В этом случае (это означает глобальное). Фактически это означает использование «Абсолютного пути пространства имен», а не «Относительный путь пространства имен». Это просто короткий путь в этом контексте и, следовательно, в глобальном пространстве имен. –

+0

@LokiAstari Не могли бы вы подробнее рассказать о различии? Это в основном то же самое, что ссылаться на файл как '/ path/to/file.txt' вместо' ./path/to/file.txt' - один относительно текущей позиции, другой - относительно определенного места? (в этом случае корневая папка) –

+0

@QPaysTaxes: хороший аналог. Но вам также нужно применить переменную PATH, чтобы лучше сделать аналог. Относительный путь будет искать в каждом каталоге пути (в то время как абсолютный не будет). В случае C++ PATH представляется каждой вложенной областью из текущей позиции. См. Https://gist.github.com/Loki-Astari/bddbdc98e8c8b9da5edc. Это делает реальные пути восприимчивыми к добавлению нового кода в родительском пространстве имен. –

1

Это должно заставить символ искать глобальную сферу.

void foo() {} // 1 

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

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

Использование этого оператора области видимости означает, что вы имеете в виду глобальную область действия.

Чтобы сэкономить драгоценное время и нажатия клавиш, ознакомьтесь с scope resolution operator without a scope.

3

Допустим, у вас есть следующие:

void bar() 
{ 
} 

struct Foo 
{ 
    void bar(); 
}; 

Если вы хотите вызвать глобальную функцию bar из функции члена Foo::bar вы используете синтаксис с пустой левой стороны:

void Foo::bar() 
{ 
    // Call the global bar function, not recursively call myself 
    ::bar(); 
} 
0

:: используется для предоставления доступа к объекту непосредственно извне объекта.

2

Он заставляет абсолютное разрешение имен.
. Без этого разрешения имени выполняется поиск относительно пути к пространству имен классов (ов)/функций.

Так предположим 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. 
      } 
     } 
    } 
}