본문 바로가기

컴퓨터

1-5. 이름공간(namespace)에 대한 소개

namespace의 필요성

같은 이름의 충돌에 대한 대처를 위해 namespace가 필요하다. 협업을 하다 보면 서로 같은 이름의 함수를 사용해 문제가 생기는 일이 비일비재하다. 이를 위한 방안이 namespace이다.

아래는 A.com이라는 회사와 B.com이라는 회사가 협업하는 중에 각자의 함수를 모아서 넣었더니 이름 충돌이 일어나는 예이다.

#include <iostream>

void function(void) {
	std::cout << "A.com에서 정의한 함수" << std::endl;
}

void function(void) {
	std::cout << "B.com에서 정의한 함수" << std::endl;
}

int main(void) {
	function();
	return 0;
}

3: A.com 회사에서는 function이라는 이름의 함수를 가져왔다.

7: B.com 회사에서도 function 이라는 이름의 함수를 가져왔다.

12: 함수를 호출하면 둘 중 어떤 함수가 호출되는가?

namespace를 이용한 문제해결

#include <iostream>

namespace A_COM {
	void function(void) {
		std::cout << "A.com에서 정의한 함수" << std::endl;
	}
}

namespace B_COM {
	void function(void) {
		std::cout << "B.com에서 정의한 함수" << std::endl;
	}
}

int main(void) {
	A_COM::function();
	B_COM::function();
	return 0;
}

3~7: A_COM이라는 namespace 안에 function 함수를 정의하고 있다.

16: A_COM namespace 안의 function 함수를 호출하고 있다. 여기서 :: 연산자를 가리켜 "범위 지정 연산자(scope resolution operator)" 라 한다. 

아래는 함수의 선언과 정의를 따로 하는 경우이다.

#include <iostream>

namespace A_COM {
	void function(void);
}

namespace B_COM {
	void function(void);
}

int main(void) {
	A_COM::function();
	B_COM::function();
	return 0;
}

namespace A_COM {
	void function(void) {
		std::cout << "A.com에서 정의한 함수" << std::endl;
	}
}

namespace B_COM {
	void function(void) {
		std::cout << "B.com에서 정의한 함수" << std::endl;
	}
}

std::cout, std::cin, std::endl에 관하여

지금까지 의미를 모르고 그냥 썼던 std::cout, std::cin, std::endl 에 대해 조금 더 알게 됐다. iostream이라는 헤더 파일에 선언된 cout, cin, endl 이 std라는 namespace 안에 있는 무엇인가 라는 것이다.

using

namespace 안의 함수를 호출할 때마다 std:: 를 붙이는 것은 여간 귀찮은 일이 아니다. 이럴 때 쓰는 키워드가 using이다.

#include <iostream>

namespace A_COM {
	void function(void) {
		std::cout << "A.com에서 정의한 함수" << std::endl;
	}
}

using A_COM::function;

int main(void) {
	function();
	return 0;
}

9: 앞으로 function이라는 이름을 참조하는 코드가 나오면 A_COM이라는 namespace 안에 선언된 function 이라는 이름을 참조하라!

#include <iostream>

namespace A_COM {
	void function(void) {
		std::cout << "A.com에서 정의한 함수" << std::endl;
	}
}

using namespace A_COM;

int main(void) {
	function();
	return 0;
}

9: A_COM 안에 선언되어 있는 이름을 참조하는 경우에는 그것이 변수이건 함수이건 namespace에 대한 선언 없이 참조하겠다!

using을 이용하면 cout, cin, endl 에도 std:: 를 안 붙여도 되겠다!

using std::cout; using std::cin; using std::endl; 또는 using namespace std; 를 하면 된다.

std namespace 안에는 cout, cin, endl 외에 다른 요소도 있을 수 있다. 그래서 귀찮더라도 각각을 using 선언해주는 앞의 방법을 사용하자.

범위 지정 연산자의 또 다른 특징

지역변수는 전역 변수의 이름을 가린다는 특징을 기억하고 아래 예제를 보자.

int val = 100;

int main(void) {
	int val = 100;
	val += 1;
	return 0;
}

1: main 함수 밖에서 선언되었으므로 val 은 전역 변수이다.

4: 전역 변수와 같은 이름의 val 이라는 지역변수가 선언되었다. 

5: 이 연산은 지역변수 val의 값을 1 증가시킨다. 여기서 만약 전역변수 val의 값을 조작하고 싶다면 어떻게 하면 될까? 5번 줄을 이렇게 수정하면 된다.

::val += 1;

범위지정 연산자가 있고 그 왼편에는 접근하고자 하는 namespace가 있어야 되는데 없다. 이것은 바로 "전역 변수로 선언되어 있는 변수 val에 접근해라"는 의미이다.

 

'컴퓨터' 카테고리의 다른 글

2-4. 레퍼런스와 함수  (0) 2019.04.05
2-3 레퍼런스(Reference)의 이해  (0) 2019.04.05
1-4. 인-라인(in-line) 함수  (0) 2019.04.05
1-3. 디폴트(Default) 매개 변수  (0) 2019.04.05
1-2. 함수 오버 로딩(Function Overloading)  (0) 2019.04.04