C++ namespace 개념
namespace가 필요한 이유
C언어 에서는 여러개의 init() 이 아래와 같이 존재할 때 init() 함수를 구분할 수 없다. (C ++에서도 아래와 같은 코드는 컴파일 에러가 역시 발생한다.) 이를 해결해 줄 수 있는 namespace 개념을 알아두어야 한다.
#include <stdio.h>
void init()
{
printf("Lego init\n");
}
void init()
{
printf("Book init\n");
}
void init()
{
printf("Default init\n");
}
int main()
{
init();
}
아래와 같이 namespace로 함수들을 구분 지을 수 있으며, 동일 init() 함수를 구분된 namespace로 호출할 수가 있다.
그냥 init()을 호출하면 global namepace 가 호출되며 Default init이 출력됨을 확인할 수 있다.
#include <stdio.h>
namespace Lego
{
void init()
{
printf("Lego init\n");
}
}
namespace Book
{
void init()
{
printf("Book init\n");
}
}
void init() // global namespace !!!
{
printf("Default init\n");
}
int main()
{
init(); // ???
Lego::init();
Book::init();
}
- C++에서는 프로그램의 크기가 커지면 namespace로 묶어서 관리할 수 있다.
- namespace를 사용하면 기능별로 다른 이름 공간을 사용하기 때문에 함수, 구조체 등의 이름 충돌을 피할 수 있다.
using
using 선언을 통해 접근이 가능하다.
using Lego::init; 으로 선언한 후, init()은 Lego 안의 init()을 호출한다.
#include <stdio.h>
namespace Lego
{
void init() { printf("Lego init\n"); }
void reset() { printf("Lego reset\n");}
}
void init() { printf("global init\n"); }
int main()
{
Lego::init(); // 한정된 이름(qualified name) 을 사용한 접근법
// 장점 : 오류의 가능성이 낮음
// 단점 : 앞에 Lego를 붙여줘야 해서 코딩량이 늘어남.
using Lego::init; // using 선언
init();
//reset(); // error 발생함 Lego::init에 대해서만 using 선언을 했고
// reset()에 대해서는 선언하지 않았기 때문.
}
using namespace
using 지시어 (directive) 사용 예시
using namespace std;
using namespace Lego;
#include <stdio.h>
namespace Lego
{
void init() { printf("Lego init\n"); }
void reset() { printf("Lego reset\n");}
}
using namespace Lego; // using directive
void init() { printf("global init\n"); }
int main()
{
::init(); // global init 을 명시적으로 불러줌.
reset(); // reset() dms Lego 안에 하나만 존재하기 때문에 실행됨.
}
using 선언이나 지시어는 함수 안, 밖에서 모두 사용 가능하다.
(함수 안에서 선언하면 당연히 함수 안에서만 유효하다.)
잘못된 사용 예시
#include <stdio.h>
namespace Lego
{
void init() { printf("Lego init\n"); }
void reset() { printf("Lego reset\n");}
}
void init() { printf("global init\n"); }
int main()
{
using namespace Lego; // using directive
init(); // compile error!!!
}
using namespace Lego; 를 선언했으나 init()이 global init인지 Lego init인지 모호해서 컴파일 에러 발생한다.
명시적으로 선언을 해주면 해결된다. Lego:: 를 붙여주어 Lego init을 호출하거나 :: 를 붙여 global이 호출되도록 할 수 있다.
에러 문구 - error: call of overloaded 'xxx' is ambiguous
친철하게 candidate 정보도 출력해주고 있다.
header(.h)파일과 cpp 파일에서 namespace선언 및 사용 방법
선언부, 구현부 모두 namespace로 묶어야 한다.
/*======== Lego.h =========*/
namespace Lego
{
void init();
void reset();
}
/*======== Lego.cpp =========*/
#include <Lego.h>
namespace Lego
{
void init()
{
}
void reset()
{
}
}
/*======== main.cpp =========*/
#include <Lego.h>
int main()
{
Lego::init();
}
아래와 같이 구현부 코드에 Lego::init(), Lego::reset() 으로 명시적으로 코드를 넣을 수도 있다.
/*======== Lego.cpp =========*/
#include <Lego.h>
void Lego::init()
{
}
void Lego::reset()
{
}
Hard work!
Hard study!
'C++' 카테고리의 다른 글
[C++] header : iostream, cstdio, cstdlib, (0) | 2021.08.04 |
---|---|
[C++] using namespace std; (0) | 2021.08.03 |
Online C++ compiler (무료 온라인 C++ 컴파일러) (0) | 2021.08.01 |
Boost C++ Libraries 설치 (Dev C++) (0) | 2021.07.29 |
c++공부 준비 : 컴파일러 (g++), dev c++ 툴 설치 (0) | 2021.07.28 |
댓글