06
10
728x90

우리가 c++를 사용해서 코딩을 하게 되면, 가장 먼저 배우는 것이 "Hello world!" 출력일 것이다.

이것을 출력할 때, cout을 사용하게 되는데, 이걸 사용하려면 맨 위에 #include <iostream>을 쓰고, using namespace std;라는것을 전역으로(함수 바깥쪽에) 선언하게 되며 형태는 아래와 같을 것이다.

 

#include <iostream>

using namespace std;

int main() {
    cout << "Hello world!" << endl;

    return 0;
}

 

위처럼 using namespace std;를 사용하지 않는다면 아래처럼 쓰면 된다.

#include <iostream>

int main() {
    std::cout << "Hello world!" << std::endl;

    return 0;
}

 

출력하고 입력받고 endl을 사용할 때마다 std::를 쓰면 상당히 귀찮기에 using namespace std;를 사용하게 된다.

 

그렇다면 이 namespace는 무것이고, using은 무엇일까?

 


namespace

우리가 함수를 작성할 때, 대부분 아래와 같은 형태로 작성을 하게 된다.

#include <iostream>

using namespace std;

int add(int n1, int n2) {
    return n1 + n2;
}

int sub(int n1, int n2) {
    return n1 - n2;
}

int main() {
    int num1 = 4, num2 = 2;
    
    cout << add(num1, num2) << endl;
    cout << sub(num1, num2) << endl;

    return 0;
}

 

덧셈, 뺄셈 함수를 만들어 출력하는데, 지금은 이름이 달라서 상관 없지만 만약 두 함수의 이름이 calculate로 같다면 어떻게 될까? 당연히 main에서 어떤 함수를 호출할지 몰라서(모호함) 에러가 나게 된다.

 

아니, 코딩하는데 누가 그런짓을 하나?

혼자 하면 그럴수도 있겠지만 여러 사람과 프로젝트를 한다면 변수, 함수 이름이 한번도 겹치치 않는다고 보장할 수는 없을 것이다.

 

이처럼 이름이 같은 식별자(변수, 함수, 형식 등의 이름)가 같은 스코프(범위) 내에 여러 개 있을 경우, 컴파일러한테 어떤애를 갖다 쓰라는건지 알려줘서 같은 이름으로 인한 충돌을 해소시키기 위해 주로 사용하게 되는 것이 namespace이다.

 

즉, namespace는 식별자가 고유하도록 보장해 주는 코드 영역을 의미한다.

 


namespace의 사용법

#include <iostream>

// namespace add
namespace add { 
    void print();    
    int calculate(int n1, int n2); 
}

// namespace sub
namespace sub {
    void print();
    int calculate(int n1, int n2); 
}

int main() {
    int num1 = 4, num2 = 2;

    add::print();
    std::cout << add::calculate(num1, num2) << '\n';

    std::cout << "===============\n";

    sub::print();
    std::cout << sub::calculate(num1, num2) << '\n';

    return 0;
}

// add 연산
void add::print() {
    std::cout << "I am ADD\n";
}
int add::calculate(int n1, int n2) {
    return n1 + n2;
}

// sub 연산
void sub::print() {
    std::cout << "I am SUB\n";
}
int sub::calculate(int n1, int n2) {
    return n1 - n2;
}

위 코드를 위에서 아래로 보면 먼저 namespace에 들어갈 함수를 선언해줬다.

가독성을 위해 안에서 함수를 정의하지 않고 main함수 아래에 정의했다.

정의할 때는 어느 namespace의 함수인지 명시하기 위해 add::, sub::를 함수의 이름 앞에 붙인다.

 

namespace를 add와 sub 두 개를 만들었으며, 그 안의 함수 이름은 서로 같다.

print()는 어떤 namespace인지 출력하고, calculate는 각각의 namespace에 맞는 연산작업을 한다.

 

이후 main에서 이름이 같은 print()와 calculate()를 호출하지만, 어떤 namespace의 함수인지 명시하기 위해 정의할때와 마찬가지로 add::, sub::를 호출할 함수 이름 앞에 붙인다.

 

이렇게 하면 

위와같이 원하는대로 연산하고 출력까지 하게 된다.

 

위에서 계속 사용했던 :: 이건 범위지정연산자(scope resolution operator)라고 하며, 예제를 보면서 감이 오겠지만 어떤 namespace의 내용물을 사용할지 지정하는 연산자이다.


using의 사용과 주의사항

using namespace XXXX; 를 하면 XXXX에 맞는 namespace를 자동으로 사용한다고 선언한 것과 같다.

그래서 cout, cin을 사용할 때 using namespace std;를 쓰면 std::cout처럼 안써도 되는 것이다.

 

그럼 add, sub namespace를 사용한 위 예제에서는 어떻게 될까?

 

using namespace add;를 하고 main()에서 print()를 하면 "I am ADD"라는 글자가 출력될 것이다.

하지만 add와 동시에 using namespace sub;까지 하고 print()를 하면 또 모호해져서 에러가 날 것이다.

 

그렇기에 using을 사용함에 있어서는 남발하지 않는 것이 주의점이 된다.

728x90
COMMENT