compound statement (block)
int x{ 5 };
{
int y{1};
std::cout << y;
std::cout << x;
x++;
int x{10};
std::cout << x;
}
std::cout << x;
{}으로 block 생성
- block 안에서의 변수는 block 끝나면 파괴됨. 이는
main과 다른 함수들도 다 동일한 얘기
- 블럭 안에서의 식별자 인식 순서
- 현재 속해있는 block에서의 식별자를 찾아 사용 (shadowing 발생 가능)
- 현재 속해있는 block에 식별자가 없다면, 바깥 block으로 이동해 찾아 사용
- 한 단계씩 상위로 이동해도 없으면, 최종적으로는 global에서 찾아 사용
- 이는
block, namespace, global space(전역변수) 등 모든 {}에 동일하게 적용됨
namespace 선언
namespace 네임 스페이스 이름
{
}
간단한 사용법
- naming collision을 예방할 수 있다
namespace::식별자로 namespace 것을 사용
::식별자로 global namespace 것을 사용
namespace Foo
{
int doSomething(int x, int y) { return x + y; }
}
namespace Goo
{
int doSomething(int x, int y) { return x - y; }
}
int doSomething(int x, int y) { return x; }
int g_swapchain*;
int main()
{
std::cout << Foo::doSomething(4, 3);
std::cout << Goo::doSomething(4, 3);
std::cout << ::doSomething(4, 3);
std::cout << doSomething(4, 3);
}
- scope resolution 없이 식별자를 사용할 경우
- 현재 속해있는 namespace에서의 식별자를 찾아 사용
- 현재 속해있는 namespace에 식별자가 없다면, 그 상위 namespace로 이동해 찾아 사용
- 한 단계씩 상위로 이동해도 없으면, 최종적으로는 global namespace에서 찾아 사용
- global에도 없다고 다른 namespace를 찾아 들어가지는 않음 (error)
void eoo() { std::cout << "eoo"; }
namespace Foo
{
void foo() { std::cout << "foo"; }
namespace Goo
{
void goo() { std::cout << "goo"; }
void print()
{
eoo();
foo();
goo();
}
}
}
int main()
{
Foo::Goo::print();
namespace Active = Foo::Goo;
Active::print();
}
- 위의 nested namespace는 아래와 같이도 선언 가능
namespace Foo::Goo
{
void print()
{
eoo();
foo();
goo();
}
}
namespace Foo
{
void foo() { std::cout << "foo"; }
}
namespace 공유
- 같은 이름의 namespace들은 하나의 namespace로 공유된다
- 다른
cpp, 헤더 파일에서 정의되어 있는 같은 이름의 namespace들도 공유
- 따라서 기존 namespace에 새로운 Identifier 추가 가능
- 단,
std는 수정 불가능
# add.h
namespace BasicMath
{
int add(int x, int y) { return x + y; }
}
#pi.h
namespace BasicMath
{
constexpr double pi{ 3.14 };
}
# main.cpp
#include "add.h"
#include "pi.h"
int main()
{
std::cout << BasicMath::pi << '\n';
std::cout << BasicMath::add(3, 4) << '\n';
}
전역변수
namespace는 global space에 존재하므로, namespace안에 있는 변수도 일반 전역변수처럼 취급
- 프로그램 시작 시 메모리에 생성되고 (0으로 초기화), 프로그램 종료시 메모리에서 사라짐
const, constexpr의 경우 전역변수 선언 시 초기화를 꼭 해주어야 함
::식별자 로 전역변수 사용 가능
int g_x;
constepxr int g_y {1};
namespace foo
{
int g_x;
}
int main() {
std::cout << g_x;
std::cout << foo::g_x;
{
std::cout << g_x;
int g_x {10};
std::cout << g_x;
std::cout << ::g_x;
}
}
Reference
learn.cpp