C++의 namespace 알아보기

Dohyun Park·2023년 9월 25일
0

C++

목록 보기
2/3

C++에서는 변수, 함수, 구조체, 클래스 등을 서로 구분하기 위해서 이름으로 사용되는 다양한 내부 식별자(identifier)를 가지고 있다.

하지만 프로그램이 복잡해지고 여러 라이브러리가 포함될수록 내부 식별자 간에 충돌할 가능성도 그만큼 커진다.

이러한 이름 충돌 문제를 C++에서는 네임스페이스(namespace)를 통해 해결하고 있다.

- TCP school -

Standard Namespace

C++의 표준 네임스페이스로, C++ 표준 라이브러리의 클래스, 함수, 객체 등이 포함되어있다.

User-Defined Namespace

사용자 정의 네임스페이스는 사용자가 필요에 따라 만들 수 있는 네임스페이스이다. 이를 통해 사용자는 자신의 코드를 조직화하고 이름 충돌을 방지할 수 있다.

#include <iostream>

void print() {
    std::cout << "Hello, Swan!\n";
}

void print() {
    std::cout << "Hello, Michael!\n";
}

int main() {
    print();
		return 0;
}

위 코드에서는 print라는 함수가 중복 정의되어있어, compile 시 오류가 발생한다.

namespace를 활용해 해결

#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()라는 코드를 사용하면 된다.

namespace in namespace

#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;
}

네임스페이스 안에 네임스페이스를 정의할 수도 있다.
위 코드는koreamichael이라는 크게 보면 2개의 네임스페이스로 정의되어있고, korea라는 네임스페이스 안에는 seoul이라는 또 하나의 네임스페이스가 정의되어있다.

메인함수를 살펴보면 korea::seoul::print() 이라는 코드를 사용했는데, 이는 korea라는 네임스페이스 안에 있는 seoul이라는 네임스페이스 내에 정의된 print라는 함수를 실행한다는 것을 의미한다.

anonymous namespace

#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! 가 두 번 출력된다.

namespace 문법 활용

기본으로 설정해주기(식별자 가져오기)

앞서 Hello, World! 를 출력하려면 std::cout << "Hello, World"; 라는 코드를 사용했다. 여기서 std를 써주지 않고 cout만 사용해 출력하는 방법도 있다.

using namespace stdusing std::cout을 통해 standard library의 모든 식별자를 현재 범위로 가져오거나 standard library의 cout만 현재 범위로 가져와서 cout << "Hello World!"를 통해서도 원하는 결과를 도출해낼 수 있는 것을 확인할 수 있다.

⚠️using namespace를 남용하면 네임스페이스 충돌과 코드 가독성 문제를 일으킬 수 있으므로 주의해 사용할 필요가 있다.

std 네임스페이스를 사용해 모든 식별자를 현재 범위로 가져오기

#include <iostream>
using namespace std;

int main() {
    cout << "Hello World!\n";
}

using namespace <네임스페이스 이름> 코드를 통해 특정 네임스페이스의 모든 식별자를 현재 범위로 가져올 수 있다.

cout만 현재 범위로 가져오기

#include <iostream>
using std::cout;

int main() {
    cout << "Hello World!\n";
}

using <라이브러리>::<식별자 이름> 코드를 통해 특정 네임스페이스의 식별자만 현재 범위로 가져올 수 있다.

profile
공부한 내용을 기록하고 생각을 정리합니다.

0개의 댓글