Brise

[C++기본] 2. namespace 본문

프로그램/C,C++

[C++기본] 2. namespace

naudhizb 2022. 1. 14. 22:59
반응형
// 2_namespace.cpp - 교재 7 page
#include <stdio.h>
//핵심 1. 관련된 함수/구조체/전역변수 등을 하나의 이름공간에서
//        관리하는 기술
// 2. 이름의 충돌을 막고, 프로그램을 논리적으로 구분할수 있다
namespace Audio
{
    void init() { printf("Audio init\n");    }
}
namespace Video
{
    void init()    { printf("Video init\n");    }
}
void init() { printf("global init\n");}

int main()
{
    init();
    Audio::init();
    Video::init();
}

C언어에서 같은 이름을 갖는 함수나 변수가 중첩되는 이슈를 방지하기 위하여 C++에서는 namespace를 이용하여 같은 이름의 함수를 다른 namespace에서 활용할 수 있다.

namespace::function(argument); 와 같은 형식으로 namespace 내부의 fucntion을 호출할 수 있다.

#include <stdio.h>

namespace Audio
{
    void init() { printf("Audio init\n"); }
}
namespace Video
{
    void init() { printf("Video init\n"); }
}
//using Video::init;

void init() { printf("global init\n"); }

int main()
{
    // namespace 안에 있는 심볼에 접근하는 3가지 방법 - 8page
    Video::init(); // 1. 완전한 이름을 사용한 접근

    using Video::init; // 2. using 선언(Declaration)
    init();
    ::init(); // 무조건 global namespace 를 사용해 달라.

//    using namespace Video; // 3. using 지시어(directive)
//    init();                // Video 이름공간 안에 있는 모든
}                        // 심볼을 Video 없이 접근 가능

namespace를 이용하여 함수를 호출하는 방법은 크게 3가지가 있다.

  1. 완전한 namespace::function을 이용하여 호출
  2. using namespace::function을 이용하여 특정 함수를 현재 namespace로 가져오는 방법
  3. using namespace namespace를 이용하여 특정 namespace의 함수를 모두 현재 namespace로 가져오는 방법.
// 2_namespace3.cpp - 9page 내용
#include <algorithm>
using namespace std;

int count = 0;

int main()
{
//    printf("%d\n", count); // std::count() 함수 인지
                           // 전역변수 count 인지 모호하다
    printf("%d\n", ::count);

    //int n = min(3, 2); // C++ 표준 함수. algorithm 헤더 필요
    int n = std::min(3, 2);
    int n2 = min(3, 2);
}

namespace를 이용하는 경우 다른 namespace에서 같은 이름의 변수를 함수로도, 변수로도 선언할 수 있다. 다만 using namespace를 사용할 때 이 부분이 충돌할 수 있는데 기존 무명 namespace를 우선시하기 위하여 ::를 이용하여 모호성을 제거할 수 있다.

// 아래 처럼 2개의 파일에서 같은 namespace를 사용해도 됩니다.
// 이경우 충돌이 아닙니다.
// 흔히, "namespace 는 열려있다" 라고 표현합니다.
// a.h
namespace Audio
{
    //..
    void foo() {}
}
// b.h
namespace Audio
{
    //..
    void foo() {}
}
#include "a.h"
#include "b.h"
#include <algorithm>
//using namespace std;
namespace Test
{
    int min(int a, int b) { return b < a ? b : a; }
}

int main()
{
    namespace Ax = std;    // namespace 별칭 만들기
    //using namespace Test;
    int n = Ax::min(1, 2);
}

namespace의 이름을 직접 사용하지 않고 alias하여 별칭을 통한 호출을 수행할 수 있다.

// 10 page 내용입니다.

// string.h   => cstring
// stdlib.h   => cstdlib

//#include <stdio.h> // printf가 global space 에 있습니다
#include <cstdio>    // printf가 std 안에 있습니다.
                     // global namespace 에도 있습니다.
// stdio.h
int printf(const char* fmt, ...) {}   // global 공간

// cstdio
#include <stdio.h>
namespace std
{
    // 전역공간의 이름을 std 안으로 가져오는 코드
    using ::printf; // 이 코드 때문에 std::printf()가 가능
}
int main()
{
    // printf 도 C++ 표준 함수 입니다
    printf("hello\n"); // ok
    std::printf("hello\n"); // 될까요 ?

}

using ::function을 이용하여 무명 namespace의 함수를 특정 namespace로 가져가 선언할 수 있다.

반응형
Comments