2018년 9월 12일 수요일

c++ namespace


처음 c++를 배울때에 우리는 보통 <iostream> 을 임포트 하여 시작했습니다.
iostream 에서는 printf 가 없기 때문에, 우리는 std::cout 을 사용하는데, 왜 이래야 하는가 에 대해 정확히 살펴 본 적은 없습니다. 그저 두루뭉실하게
java 따위에서 타 클래스를 명시하여 함수를 이용하는것이다 정도 였는데요,

마침 수업중에 namespace 에 대해서 정리해 오라는 과제를 던지는것을 봤습니다.
나도 궁금한 사항이니 이에 대해 알아보고, 정리해 보았습니다.

개발환경에 학습 이상으로 넘어가게 되면, 각 개발자마다 맡아 작업하는 cpp 파일들이 따로 있게 될 것 입니다.

따로 작업한 cpp 파일들을 합쳐, 작동시키는데에는 문제가 없을것 입니다.

하지만 변수 혹은 함수의 이름이 동일하게 되면 어떨까요?

class a
 int a = 0 ;

class b
 int a = 0;


메인 :  "a ?"

이제 골치가 아파지기 시작합니다. 하지만 놀랍게도 실무에서는 변수나 함수 이름을 고의로 통일시키는 경우도 있습니다. 전역적으로 두 소스파일에서 같은 변/함수를 사용할때 같이 말이죠.

이런 경우에는 선언할 변수를 가진 소스파일은 그대로 두나, 타 소스파일의 변수를 같이 사용하고지 하는 소스의 경우는 데이터 타입 앞에 extern 을 붙히게 됩니다.
calss a
 int a = 0
class b
 extern int a

메인 : "a 는 class a 에서 만든 변수이며, class b는 class a의 변수를 참조한다!"

이렇게 사용이 가능하다는 말이죠.
이떄 extern을 명시한 변수는 초기화를 선언과 동시에 해서는 안됩니다. 이럴경우 extern이 아닌 class b 에서 생성된 변수 a로 바뀌어 버립니다.

그럼 의도적으로 동일한 이름의 변/함수가 아닌 경우에는 어떻게 할까요?
가장 쉬운 방법은 이름을 바꾸는것 입니다. 하지만 이건 너무 무식하지요, 조금더 쓸모있게 해 봅니다.
class a
 static int a = 0
class b
 static int a = 10
메인 : "class a 에서만 존재한 변수 a 와, class b 에서만 존재하는 변수 a 두개가 있다!"

근본적인 문제는 해결했으나, 만일 class a 나 class b 가 a 변수를 서로 다른 class에게 공유를 할 계획이라거나, 더 많은 소스파일들로 인해, extern도 사용하기가 힘들어 진다면?
static은 해당 class 내에서만 작동하기 때문에, 지금 코드로는 문제가 있습니다.

이를해결하기 위해 나온것이...
namespace 가 등장했습니다!

namespace 는 변수나 함수, 심지어 class에 사용이 가능합니다.
namespace first {
 int a = 0;
}
namespace second {
 int a = 1;
}
namespace third {
 int a = 2;
}

main(){
cout << first::a << second::a << third::a << endl;
//expect result is 0 1 2
}

c+ 을 해보신 분이라면 어느정도 파악은 하고 계시겠지만, namespace를 명시하지 않아도, 묵시적으로 namespace가 선언되어 있습니다.
그럼 어디로? 전역 네임스페이스 공간으로 되어있습니다. 우리가 보통 명시하지 않은 변수 함수 선언은 전역 네임스페이스 공간으로 선언이 되기 때문에,

좋아요, 그럼 변수와 함수를 여러개 사용하는 예제를 보시죠

namesapce myNamespace{
 void func(){}
 int a = 0 ;
}
using myNameapce ::func
main(){
 cout << myNamespace::a << endl
 // myNamespace는 using이 아니기 때문에 명시가 필요
 func()
// using으로 myNamespace 내부의 func를 스코프 했기 때문에, myNamespace :: func()
}

이즘되면 클래스랑 동일하다는 생각을 가질수 도 있는데, 그렇지는 않습니다.
클래스와 네임스페이스는 다르다는것을 명심해야 합니다.


( 그낭 글씨치기엔 귀찮아서 코드 사진으로 대체)
위코드는 myNamespace 를 변수로 선언해서 사용해 부며,
myNamespace 안의 class를 사용하는 예제입니다.
위에서 언급됬다싶이, namespace 와 class는 비슷해 보이지만 다르기 떄문에, 혼동하지 않도록 해야할 것 입니다!

댓글 없음:

댓글 쓰기