C ++ : 네임 스페이스 — 헤더 및 소스 파일에서 올바르게 사용하는 방법?


88

인터페이스 선언 파일 ( *.h또는 *.hpp)과 해당 구현 파일 ( *.cpp) 의 두 소스 파일 쌍을 고려하십시오 .

송출 *.h파일에 다음처럼 :

namespace MyNamespace {
  class MyClass {
  public:
    int foo();
  };
}

소스 파일에서 네임 스페이스를 사용하는 두 가지 다른 사례를 보았습니다.

*.cpp 연습 # 1 보여주기 :

#include "MyClass.h"
using namespace MyNamespace;

int MyClass::foo() { ... }

*.cpp 연습 # 2 보여주기 :

#include "MyClass.h"
namespace MyNamespace {

  int MyClass::foo() { ... }

}

내 질문 : 이 두 관행 사이에 차이점이 있으며 하나가 다른 것보다 더 나은 것으로 간주됩니까?


30
옵션 3도 있습니다 int MyNamespace::MyClass::foo() .... 예를 들어 .
Benjamin Bannier


@Dave는 중복되지 않습니다. 이 질문들은 서로를 보완합니다. Dave가 제공 한 링크를이 질문에 "Read also ..."로 추가하는 것이 좋습니다. 내 질문은 초보자가 올바른 스타일을 선택하는 데 도움이 될 것입니다.
nickolay

답변:


62

코드 가독성 관점에서 볼 때 이러한 이유로 # 2 방법을 사용하는 것이 제 생각에는 아마도 더 좋습니다.

using번에 여러 개의 네임 스페이스 가 될 수 있으며 해당 줄 아래에 작성된 모든 개체 또는 함수는 해당 네임 스페이스에 속할 수 있습니다 (이름 충돌 제외). 전체 파일을 namespace블록으로 래핑하는 것이 더 명확하며 .cpp 파일 내에서 해당 네임 스페이스에 속하는 새 함수와 변수를 선언 할 수도 있습니다.


Dave가 자신의 의견에서 귀하의 질문에 연결 한 질문은 또한 귀하
Dan F

여러분, 누구의 답을 선택해야할지 정말 모르겠습니다. 그들은 서로를 보완하면서 교차점이 있습니다.
nickolay

CLion과 같은 일부 IDE는 옵션 / 실습 # 2를 사용하는 경우에만 구현을 감지한다는 점을 인정하기 위해 주석을 달면됩니다.
PedroTanaka 2015

@PedroTanaka 여전히 이것이 사실입니까? 나는 그러한 문제를 발견하지 못했습니다.
John McFarlane

@JMcF 댓글을 게시 한 이후로 확인하지 않았습니다. Clion의 초기 버전에서는 문제가 발생했습니다.
PedroTanaka

51

가장 분명한 것은 표시하지 않은 옵션입니다.

int MyNamespace::MyClass::foo()
{
    //  ...
}

또한 매우 장황합니다. 대부분의 사람들에게 너무 많이. 때문에 using namespace내 경험에 적어도 이름 충돌에 대한 recepe이, 그리고 매우 제한된 범위와 장소를 제외하고 피해야한다, 나는 일반적으로 당신의 # 2를 사용합니다.


3
감사합니다. 우리는 함께 네임 스페이스 사용자를위한 좋은 FAQ 페이지를 만들었습니다. :)
nickolay

2
여러분, 누구의 답을 선택해야할지 정말 모르겠습니다. 그들은 서로를 보완하면서 교차점이 있습니다.
nickolay

10

이 두 관행 사이에 차이점이 있습니까?

예. # 1 및 # 2는 각각 using-directive네임 스페이스 정의의 예 입니다. 이 경우에는 사실상 동일하지만 다른 결과가 있습니다. 예를 들어,와 함께 새 식별자를 도입하면 MyClass::foo범위가 달라집니다.

#1:

using namespace MyNamespace;
int x;  // defines ::x

# 2 :

namespace MyNamespace {
  int x;  // defines MyNamespace::x
}

하나가 다른 것보다 더 나은 것으로 간주됩니까?

# 1 장점 : 조금 더 간결합니다. 실수로 무언가를 소개하기가 더 어렵습니다.MyNamespace 무의식적으로 . 단점 : 기존 식별자를 실수로 가져올 수 있습니다.

# 2 장점 : 기존 식별자의 정의와 새 식별자의 선언이 모두 MyNamespace. 단점 : 실수로 MyNamespace.

# 1과 # 2에 대한 비판은 .NET Framework의 멤버 정의에만 관심이있을 때 전체 네임 스페이스를 참조한다는 것입니다 MyNamespace::MyClass. 이것은 무겁고 의도를 제대로 전달하지 않습니다.

# 1의 가능한 대안 은 관심있는 식별자 만 포함 하는 using-declaration 입니다.

#include "MyClass.h"
using MyNamespace::MyClass;

int MyClass::foo() { ... }

4

또한 cpp 파일에서 템플릿 전문화를 구현해야하는 이유 때문에 결정 using namespace하고 다음 문제가 발생할 것이라는 점 을 추가하고 싶습니다 .

// .h file
namespace someNameSpace
{
  template<typename T>
    class Demo
    {
      void foo();
    };
}

// .cpp file
using namespace someNameSpace;

template<typename T>
void Demo<T>::foo(){}

// this will produce
// error: specialization of 'template<class T> void someNameSpace::Demo<T>::foo()' in different namespace [-fpermissive]
template<>
void Demo<int>::foo(){}

그렇지 않으면 # 2 방법을 적용하면 괜찮습니다.


0

using-declaration을 사용 하여 한 가지 더 방법을 추가하고 싶습니다 .

#include "MyClass.h"
using MyNamespace::MyClass;

int MyClass::foo() { ... }

이렇게하면 클래스에 많은 함수가있는 경우 네임 스페이스 이름을 여러 번 입력하지 않아도됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.