10.4 스코프 지정
C++프로그래머라면 스코프(Scope)라는 개념에 익숙해져야 한다. 프로그램 내의 변수, 함수, 클래스 등의 모든 이름은 특정한 유효 범위, 즉 스코프를 가진다. 그리고 네임스페이스, 함수 정의, 클래스 정의, 중괄호 쌍을 이용한 블록 정의를 통해 스코프를 만들 수도 있다. 어떤 변수나 함수 클래스에 접근하려 할 때는 가장 가까운 스코프에서부터 가장 먼 전역 스코프까지 차례로 찾게 된다. 네임 스페이스, 함수, 클래스, 중괄호 쌍 블록 모두 이름이 존재하지 않으면 전역 스코프에 있는 것으로 간주한다.
만약 전역 스코프에서도 찾지 못하면 컴파일러가 정의되지 않은 심벌이라는 에러 메시지를 출력한다.
어떤 경우에는 같은 이름의 다른 스코프 때문에 스코프가 가려지기도 한다. 또 어떤 경우에는 접근해야 하는 스코프가 특정 소스 라인에서 가장 먼저 적용되어야 하는 디폴트 스코프가 아닐 수도 있다. 만약 디폴트 스코프 대신 다른 스코프의 적용을 받아야 한다면 스코프 지정 연산자 :: 를 사용해야 한다. 예를 들어 클래스의 static메서드를 접근하는 방법으로 해당 클래스 이름에 스코프 지정 연산자를 붙여서 메서드를 호출할 수 있다.
또 다른 방법으로 객체의 메서드로 호출할 수도 있다. 다음 예는 이러한 방법을 보여준다. 다음 코드에서는 Demo클래스의 static get()메서드, 전역 함수 get(), 네임 스페이스 NS에 속한 함수 get()을 정의하고 있다.
class Demo
{
public:
static int get() { return 5; }
};
int get() { return 10; }
namespace NS
[
int get() { return 20; }
};
전역 스코프는 따로 이름을 가지지 않는다. 하지만
앞첨자 없이 스코프 지정 연산자를 이용하면 전역 스코프에 접근할 수 있다. 위 코드에서 정의된 여러 get()함수는 다음과 같이 명시적으로 전역 스코프를 지정하여 선택할 수 있다.
int main()
{
Demo* pd = std;:make_unique<Demo>();
Demo d;
std::cout << pd->get() << std::endl; // 5를 출력함
std::cout << d.get() << std::endl; // 5를 출력함
std::cout << NS::get() << std::endl; // 20를 출력함
std::cout << Demo::get() << std::endl; // 5를 출력함
std::cout << ::get() << std::endl; // 10를 출력함
std::cout << get() << std::endl; // 10를 출력함
return 0;
}
만약 네임스페이스 NS가 이름 없이 선언(즉, namespace NS { ... } 대신 namespace { ... } 사용 ) 된다면, get()함수 호출 코드는 컴파일이 안된다. 이름 없는 네임스페이스에 속한 get()함수와 전역 스코프에 정의된 get()함수 중 어느 함수를 사용해야 할지 결정할 수 없어 컴파일 에러가 발생한다.
std::cout << get() << std::endl;
main()함수 앞에서 다음과 같이 using구문을 이용해서 네임스페이스 NS를 디폴트 스코프화해도 같은 문제로 컴파일 에러가 발생한다.
using namespace NS;
'전문가를 위한 C++정리' 카테고리의 다른 글
10. C++의 까다롭고 유별난 부분들 10.6 헤더 파일 (0) | 2024.03.19 |
---|---|
10. C++의 까다롭고 유별난 부분들 10.5 C++11 / C++14 (0) | 2024.03.14 |
10. C++의 까다롭고 유별난 부분들 10.3 타입과 캐스팅 (0) | 2024.03.08 |
10. C++의 까다롭고 유별난 부분들 10.2 키워드 혼동 (0) | 2024.03.07 |
10. C++의 까다롭고 유별난 부분들 10.1 참조형 (0) | 2024.03.05 |