프로그래밍 공부
작성일
2024. 3. 11. 18:10
작성자
WDmil
728x90

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;

 

728x90