C++에서는 변수, 함수, 구조체, 클래스 등을 서로 구분하기 위해서 이름으로 사용되는 다양한 내부 식별자(identifier)를 가지고 있다.
하지만 프로그램이 복잡해지고 여러 라이브러리가 포함될수록 내부 식별자 간에 충돌할 가능성도 그만큼 커진다.
이러한 이름 충돌 문제를 C++에서는 네임스페이스(namespace
)를 통해 해결하고 있다.
- TCP school -
C++의 표준 네임스페이스로, C++ 표준 라이브러리의 클래스, 함수, 객체 등이 포함되어있다.
사용자 정의 네임스페이스는 사용자가 필요에 따라 만들 수 있는 네임스페이스이다. 이를 통해 사용자는 자신의 코드를 조직화하고 이름 충돌을 방지할 수 있다.
#include <iostream>
void print() {
std::cout << "Hello, Swan!\n";
}
void print() {
std::cout << "Hello, Michael!\n";
}
int main() {
print();
return 0;
}
위 코드에서는 print
라는 함수가 중복 정의되어있어, compile 시 오류가 발생한다.
#include <iostream>
namespace swan {
void print() {
std::cout << "Hello, Swan!\n";
}
}
namespace michael {
void print() {
std::cout << "Hello, Michael!\n";
}
}
int main() {
michael::print();
return 0;
}
위 코드에서는 swan
이라는 네임스페이스 안에 print
라는 함수를, michael
이라는 네임스페이스 안에 print
함수를 각각 정의하도록 수정하였다.
메인 함수에서 michael::print()
라는 코드를 사용했으므로, 이는 michael이라는 네임스페이스에 있는 print 함수를 실행한다는 것을 의미한다.
따라서 Hello, Michael!\n
이 출력되게 된다.
Hello, Swan!\n
을 출력하고 싶다면 swan:print()
라는 코드를 사용하면 된다.
#include <iostream>
namespace korea {
namespace seoul {
void print() {
std::cout << "Welcome to Seoul!\n";
}
}
}
namespace michael {
void print() {
std::cout << "Hello, Michael!\n";
}
}
int main() {
korea::seoul::print();
return 0;
}
네임스페이스 안에 네임스페이스를 정의할 수도 있다.
위 코드는korea
와 michael
이라는 크게 보면 2개의 네임스페이스로 정의되어있고, korea
라는 네임스페이스 안에는 seoul
이라는 또 하나의 네임스페이스가 정의되어있다.
메인함수를 살펴보면 korea::seoul::print()
이라는 코드를 사용했는데, 이는 korea
라는 네임스페이스 안에 있는 seoul
이라는 네임스페이스 내에 정의된 print
라는 함수를 실행한다는 것을 의미한다.
#include <iostream>
namespace hello {
namespace world {
void print() {
std::cout << "Hello World!\n";
}
}
}
namespace {
void print() {
std::cout << "Hello, Anonymous Namespace!\n";
}
}
int main() {
print(); // Hello, Anonymous Namespace!
::print(); // Hello, Anonymous Namespace!
return 0;
}
anonymous namespace는 자신이 위치한 파일 내에서만 존재한다.
namespace를 선언할 때 별도의 이름을 쓰지 않고 namespace를 선언하면 anonymous namespace를 만들 수 있다.
위 코드를 살펴보면 익명 네임스페이스에 print라는 함수를 만들고, std::cout Hello, Anonymous Namespace!
를 출력하고 있다.
실행 시 anonymous namespace의 print 함수가 두 번 실행되므로, Hello, Anonymous Namespace!
가 두 번 출력된다.
앞서 Hello, World! 를 출력하려면 std::cout << "Hello, World";
라는 코드를 사용했다. 여기서 std를 써주지 않고 cout만 사용해 출력하는 방법도 있다.
using namespace std
와 using std::cout
을 통해 standard library의 모든 식별자를 현재 범위로 가져오거나 standard library의 cout만 현재 범위로 가져와서 cout << "Hello World!"
를 통해서도 원하는 결과를 도출해낼 수 있는 것을 확인할 수 있다.
⚠️using namespace
를 남용하면 네임스페이스 충돌과 코드 가독성 문제를 일으킬 수 있으므로 주의해 사용할 필요가 있다.
#include <iostream>
using namespace std;
int main() {
cout << "Hello World!\n";
}
using namespace <네임스페이스 이름>
코드를 통해 특정 네임스페이스의 모든 식별자를 현재 범위로 가져올 수 있다.
#include <iostream>
using std::cout;
int main() {
cout << "Hello World!\n";
}
using <라이브러리>::<식별자 이름>
코드를 통해 특정 네임스페이스의 식별자만 현재 범위로 가져올 수 있다.