C++ Namespaces
C++ 프로그래밍, 네임스페이스 ( Namespaces )
C++ 언어의 네임스페이스 개념
C++ 언어에서 네임스페이스(Namespaces)란 말 그대로 이름이 속한 공간(논리적인 그룹)을 의미한다. 여기서 이름은 변수, 함수, 클래스, 또 다른 네임스페이스의 이름을 말한다. 개발자는 이런 이름들이 속한 논리적인 그룹을 지정할 수 있고 그 그룹 안에 선언되는 이름은 중복할 수 없다. 그러나 네임스페이스가 서로 다르다면 동일한 이름을 사용할 수 있다.
서로 관련성이 있는 코드는 특정 이름을 가진 네임스페이스 안에 선언하면 하나의 논리적인 그룹이 되므로 해당 네임스페이스에 접근하여 그 안에 선언된 엔티티를 사용할 때는 특별한 키워드를 사용하여 선언해야 한다.
네임스페이스 안에는 다양한 엔티티가 선언될 수 있는데, 여기서 엔티티(Entity)란 변수, 함수, 클래스, 객체변수 등 이름으로 표현되는 것들을 말한다
네임스페이스 선언
namespace { /* 엔티티(Entities) 선언 */ }
예)
namespace ns1 { int n = 0; }
특정 네임스페이스에 접근하여 그 안에 있는 엔티티를 사용할 때
네임스페이스 이름:: 엔티티 이름; // Scope 연산자( :: )를 사용한다
예)
ns1::n = 10;
다른 네임스페이스를 현재 공간에서 직접 접근할 때(네임스페이스 이름을 제외하고 사용하는 경우)
using 네임스페이스 이름 :: 엔티티 이름;
위와 같이 선언한 후에 현재 영역에 선언된 에티티처럼 사용하면 된다
예)
using ns1::n;
n = 20; // 네임스페이스 이름을 사용하지 않고도 네임스페이스 안에 있는 변수를 사용할 수 있다
특정 네임스페이스 안에 있는 모든 엔티티들을 네임스페이스 이름 없이 바로 접근하려는 경우
using namespace ns1; // 이렇게 선언하면 해당 네임스페이스 안에 있는 모든 엔티티들을 직접하는 것처럼 사용할 수 있다
예)
using namespace ns1;
n = 100;
네임스페이스의 이름을 이용하여 그 안에 있는 엔티티를 사용하는 예
#include <iostream> #include <locale> using namespace std; // 네임스페이스 선언. 변수, 함수, 클래스, 객체, 다른 네임스페이스 등이 선언될 수 있다 namespace ns1 { int n = 0; // 변수 void printNum() { // 함수 wprintf(L"ns1, n=%d \n", n); } class CSample { // 클래스 int n; public: CSample(int n){ this->n = n; } void print(){ wprintf(L"ns1, CSample.n=%d \n", n); } }; CSample sample(10); // 객체 }; namespace ns2 { int n = 0; void printNum() { wprintf(L"ns2, n=%d \n", n); } class CSample { int n; public: CSample(int n){ this->n = n; } void print(){ wprintf(L"ns2, CSample.n=%d \n", n); } }; CSample sample(20); } int main() { setlocale(LC_ALL, ""); wcout << L"C++ 네임스페이스(Namespace)" << endl; // 네임스페이스에 접근하여 그 안에 있는 변수를 사용하는 예 ns1::n = 100; // 네임스페이스를 달리하여 동일한 이름의 엔티티가 선언될 수 있다 ns2::n = 200; ns1::printNum(); // 100 ns2::printNum(); // 200 ns1::CSample sample1(5); // 네임스페이스 안에 있는 클래스의 객체생성 ns2::CSample sample2(7); // 위에서 생성한 객체의 함수 호출 sample1.print(); // 5 sample2.print(); // 7 // 네임스페이스 안에서 생성된 객체의 함수 호출 ns1::sample.print(); // 10 ns2::sample.print(); // 20 return 0; }
네임스페이스 안에 있는 특정 엔티티에만 직접 접근하려는 경우 (using 을 이용하여 각각 선언한다)
#include <iostream> #include <locale> using namespace std; // 네임스페이스 선언. 변수, 함수, 클래스, 객체, 다른 네임스페이스 등이 선언될 수 있다 namespace ns1 { int n = 0; // 변수 void printNum() { // 함수 wprintf(L"ns1, n=%d \n", n); } class CSample { // 클래스 int n; public: CSample(int n){ this->n = n; } void print(){ wprintf(L"ns1, CSample.n=%d \n", n); } }; CSample sample(10); // 객체 }; namespace ns2 { int n = 0; void printNum() { wprintf(L"ns2, n=%d \n", n); } class CSample { int n; public: CSample(int n){ this->n = n; } void print(){ wprintf(L"ns2, CSample.n=%d \n", n); } }; CSample sample(20); } int main() { setlocale(LC_ALL, ""); wcout << L"C++ 네임스페이스(Namespace)" << endl; // 네임스페이스에 있는 몇개의 엔티티만 직접 접근하려는 경우 using 으로 각각 선언한다 using ns1::n; // 기본형 변수 using ns1::printNum; // 함수 using ns2::CSample; // 클래스 using ns2::sample; // 객체 n = 30; printNum(); // 30 CSample samp(50); samp.print(); // 50 sample.print(); // 20 // 직접 접근할 수 없는 엔티티는 다음과 같이 네임스페이스 이름을 사용해야 한다 ns2::n = 70; ns2::printNum(); return 0; }
특정 네임스페이스 안에 있는 모든 엔티티에 직접 접근하려는 경우 ( using namespace ns1 으로 선언한다)
#include <iostream> #include <locale> using namespace std; // 네임스페이스 선언. 변수, 함수, 클래스, 객체, 다른 네임스페이스 등이 선언될 수 있다 namespace ns1 { int n = 0; // 변수 void printNum() { // 함수 wprintf(L"ns1, n=%d \n", n); } class CSample { // 클래스 int n; public: CSample(int n){ this->n = n; } void print(){ wprintf(L"ns1, CSample.n=%d \n", n); } }; CSample sample(10); // 객체 }; namespace ns2 { int n = 0; void printNum() { wprintf(L"ns2, n=%d \n", n); } class CSample { int n; public: CSample(int n){ this->n = n; } void print(){ wprintf(L"ns2, CSample.n=%d \n", n); } }; CSample sample(20); } int main() { setlocale(LC_ALL, ""); wcout << L"C++ 네임스페이스(Namespace)" << endl; // 특정 네임스페이스 안에 있는 모든 엔티티에 직접 접근하려는 경우 using namespace ns1; n = 30; printNum(); // 30 CSample samp(50); samp.print(); // 50 sample.print(); // 10 // 직접 접근할 수 없는 엔티티는 다음과 같이 네임스페이스 이름을 사용해야 한다 ns2::n = 70; ns2::printNum(); // 70 return 0; }
중첩된 네임스페이스와 네임스페이스 별칭을 사용하는 예
#include <iostream> #include <locale> using namespace std; // 네임스페이스 선언. 변수, 함수, 클래스, 객체, 다른 네임스페이스 등이 선언될 수 있다 namespace ns1 { int n = 0; // 변수 void printNum() { // 함수 wprintf(L"ns1, n=%d \n", n); } class CSample { // 클래스 int n; public: CSample(int n){ this->n = n; } void print(){ wprintf(L"ns1, CSample.n=%d \n", n); } }; CSample sample(10); // 객체 // 상위 네임스페이스에서는 하위 네임스페이스에 직접 접근 불가(그 반대는 가능) namespace ns1sub { int n2 = 0; void printNum2() { wprintf(L"ns2, n2=%d \n", n2); } class CSample2 { int n; public: CSample2(int n){ this->n = n; } void print(){ wprintf(L"ns2, CSample.n=%d \n", n); } }; CSample2 sample2(20); } }; int main() { setlocale(LC_ALL, ""); wcout << L"C++ 네임스페이스(Namespace)" << endl; // 중첩 네임스페이스에 접근하는 예 using namespace ns1; // ns1에는 직접 접근가능 ns1sub::sample2.print(); // 하위에 있는 네임스페이스인 ns1sub는 직접 접근안됨 namespace ns2 = ns1::ns1sub; // 네임스페이스 별칭 선언 ns2::sample2.print(); // 위에서 선언한 네임스페이스 별칭 이용 using namespace ns1::ns1sub; // 하위에 있는 네임스페이스에 직접 접근 선언 sample2.print(); return 0; }