네임스페이스는 코드에서 이름이 서로 충돌하는 문제를 해결하기 위해 나온 개념이다. 예를 들어 foo() 함수를 정의해서 코드를 작성하다가 외부에 라이브러리가 필요해서 추가 했더니 외부 라이브러리에도 foo() 함수가 있을 수 있다.
이때 컴파일러는 foo()란 이름만 보고서는 어느 함수를 가리키는지 알 수 없다. 외부 라이브러리에 정의된 함수의 이름은 바꿀 수 없고, 내가 작성한 코드를 고치기엔 일이 너무 커져 버린다.
이런 문제는 네임 스페이스를 사용하여 해결 할 수 있다. 어떤 이름이 어디에 속해 있는지 문맥을 정의할수 있기 때문이다. 아래는 예시이다.
// namespaces.h
namespace mycode {
void foo();
}
네임스페이스는 이렇게 함수나 메서드의 선언뿐만 아니라 구현 부분도 묶을 수 있다. 예를 들어 foo() 함수의 구현 부분을 에 작성할 때 namespaces.cpp 네임스페이스를 지정하는 방법은 다음과 같다.
#include <iostream> // global
#include "namespaces.h" // local
void mycode::foo()
{
// TODO:
}
또는 다음과 같이 작성해도 된다.
#include <iostream>
#include "namespaces.h"
namespace mycode {
void foo()
{
// TODO:
}
}
위처럼 foo()를 mycode 네임스페이스 아래에 두면 외부 라이브러리에 foo()가 있더라도 서로 구분할 수 있다. 네임스페이스를 적용한 foo()를 호출하려면 ::(스코프 지정연산자 scope resolution operator)를 이용하여 함수 이름 앞에 네임스페이스를 붙인다.
mycode::foo(); // mycode 네임스페이스를 적용한 foo() 함수를 호출 한다.
mycode 네임스페이스를 블록 안에서 접근할 때는 네임스페이스를 접두어로 붙이지 않아도 된다. 이렇게 네임스페이스를 생략하면 코드의 가독성을 좀 더 높일 수 있다. 또한 using 지시자를 이용하면 네임스페이스 접두어를 생략할 수도 있다. 컴파일러는 using 지시자를 보면 그 뒤에 나오는 문장부터는 using에 지정된 네임스페이스에 속하는 것으로 처리한다. 예를 들면 다음과 같다.
#include "namespaces.h"
using namespace mycode;
int main()
{
foo(); // mycode::foo(); 와 같다.
return 0;
}
헤더 파일 안에서는 절대로 using 문을 작성하면 안 된다. 그러면 그 헤더 파일을 인클루드하는 모든 파일에서 using 문으로 지정한 방식으로 호출 해야 한다.
C++17 에서는 중첩된 네임스페이스(nested namespace)를 좀 더 쉽게 사용할 수 있도록 개선했다. 중첩된 네임스페이스란 네임스페이스 안에 있는 네임스페이스를 말한다. C++17 이전에는 다음과 같이 작성했다.
namespace MyLibraries {
namespace Networking{
namespace FTP{
/* ... */
}
}
}
C++17부터는 다음과 같이 간결해 졌다.
namespace MyLibraries::Networking::FTP {
/* ... */
}
네임스페이스 앨리어스 namespace alias를 사용하면 네임스페이스의 이름을 다르게 표현하거나 기존 이름을 좀 더 짧게 만들 수 있다. 예를 들면 다음과 같다.
namespace MyFTP = MyLibraries::Networking::FTP;
익명네임스페이스
네임스페이스 관련 구글링을 하다가 숟가락의 프로그래밍 블로그에서 익명네임스페이스의 관한 포스팅을 보았다. 익명 네임스페이스안에 변수와 함수의 파일 범위를 한정짓는 C++ 이디엄처럼 자주 사용되는 기법이다.
// foo.cpp
namespace // anonymous namespace
{
const int INTERNAL_CONSTANT = 42;
std::string FileName = "file.txt";
void FreeFunction {
std::cout << "Free function called" << std::endl;
}
}
위와 같이 익명의 네임스페이스를 만들어버리면, 이름이 없기 때문에 외부(다른 번역단위)에서 사실상 이 네임스페이스에 접근하는 것은 불가능해진다.
실제로 익명 네임스페이스는 정말로 이름이 없진 않다. 단지 컴파일러가 임의의 이름을 붙여 버리기 때문에 사실상 이 네임스페이스를 알기 어렵다고 하는 것이다.
Const 레퍼런스 전달 방식 (0) | 2020.06.22 |
---|---|
스마트포인터 (0) | 2020.06.22 |
virtual inheritance in c++ (0) | 2019.09.05 |
소멸자 (0) | 2018.09.30 |
STL VECTOR 오름차순, 내림차순 정렬 하기 (0) | 2018.08.21 |
댓글 영역