성명서 네임스페이스 표준 사용 일반적으로 나쁜 습관으로 간주됩니다. 이 명령문의 대안은 유형을 선언할 때마다 범위 연산자(::)를 사용하여 식별자가 속한 네임스페이스를 지정하는 것입니다.
이 진술은 우리가 타이핑을 하지 않아도 되지만 표준:: std 네임스페이스에 정의된 클래스나 유형에 액세스하려고 할 때마다 해당 이름 전체를 가져옵니다. 성병 프로그램의 현재 네임스페이스에 네임스페이스를 추가합니다. 이것이 왜 그렇게 좋지 않은지 이해하기 위해 몇 가지 예를 들어보겠습니다.
std 네임스페이스의 cout을 사용하고 싶다고 가정해 보겠습니다. 그래서 우리는 쓴다
예시 1:
CPP
#include> using> namespace> std;> > cout <<>' Something to Display'>;> |
>
>
이제 개발의 나중 단계에서 우리는 foo라는 라이브러리에 맞춤 구현된 다른 버전의 cout을 사용하려고 합니다(예를 들어).
CPP
#include> #include> using> namespace> std;> > cout <<>' Something to display'>;> |
>
>
cout이 어느 라이브러리를 가리키는지 이제 모호함이 있다는 것을 알 수 있습니까? 컴파일러는 이를 감지하고 프로그램을 컴파일하지 않을 수 있습니다. 최악의 경우 프로그램은 여전히 컴파일되지만 잘못된 함수를 호출할 수 있습니다. 식별자가 속한 네임스페이스를 지정하지 않았기 때문입니다.
식별자 이름 충돌을 해결하기 위해 네임스페이스가 C++에 도입되었습니다. 이를 통해 두 개체가 동일한 이름을 가질 수 있지만 서로 다른 네임스페이스에 속하는 경우 다르게 처리될 수 있습니다. 이 예에서는 정반대의 현상이 어떻게 발생했는지 확인하세요. 이름 충돌을 해결하는 대신 실제로 이름 충돌을 만듭니다.
메가바이트와 기가바이트의 차이점은 무엇입니까
네임스페이스를 가져올 때 기본적으로 모든 유형 정의를 현재 범위로 가져옵니다. std 네임스페이스는 엄청납니다. 여기에는 수백 개의 사전 정의된 식별자가 있으므로 개발자가 std 라이브러리에 의도한 개체에 대한 또 다른 정의가 있다는 사실을 간과할 수 있습니다. 이를 인식하지 못한 채 자체 구현을 지정하고 프로그램의 후반부에서 사용되기를 기대할 수도 있습니다. 따라서 현재 네임스페이스에는 동일한 유형에 대한 두 개의 정의가 존재하게 됩니다. 이는 C++에서는 허용되지 않으며 프로그램이 컴파일되더라도 어떤 정의가 어디에 사용되는지 알 수 있는 방법이 없습니다.
문제에 대한 해결책은 범위 연산자(::)를 사용하여 식별자가 속한 네임스페이스를 명시적으로 지정하는 것입니다. 따라서 위의 예에 대한 한 가지 가능한 해결책은 다음과 같습니다.
CPP
#include> #include> > // Use cout of std library> std::cout <<>'Something to display'>;> > // Use cout of foo library> foo::cout <>'Something to display'>;> |
>
>
하지만 타자를 쳐야 해서 표준:: 유형을 정의할 때마다 지루합니다. 또한 많은 유형 정의로 인해 코드가 더 복잡해 보이고 코드를 읽기 어렵게 만듭니다. 예를 들어 프로그램에서 현재 시간을 가져오는 코드를 생각해 보세요.
예시 2:
CPP
#include> #include> > auto> start = std::chrono::high_performance_clock::now()> > // Do Something> > auto> stop> >= std::chrono::high_peformance_clock::now();> auto> duration> >= std::duration_cast(stop - start);> |
>
>
복잡하고 긴 유형 정의로 가득 찬 소스 코드는 읽기가 쉽지 않습니다. 코드 유지 관리가 개발자에게 가장 중요하기 때문에 이는 개발자가 피하려고 하는 것입니다.
이 딜레마를 해결하는 몇 가지 방법이 있습니다. 즉, std 키워드로 코드를 어지럽히지 않고 정확한 네임스페이스를 지정하는 것입니다.
typedef 사용을 고려해보세요.
typedef를 사용하면 긴 유형 정의를 작성하지 않아도 됩니다. 예제 1에서는 std 라이브러리와 foo에 대한 두 개의 typedef를 사용하여 문제를 해결할 수 있습니다.
CPP
#include> #include> > typedef> std::cout cout_std;> typedef> foo::cout cout_foo;> > cout_std <<>'Something to write'>;> cout_foo <<>'Something to write'>;> |
>
>
전체 네임스페이스를 가져오는 대신 잘린 네임스페이스를 가져옵니다.
예제 2에서는 std 아래에 chrono 네임스페이스만 가져올 수 있었습니다.
CPP
#include> #include> > // Import only the chrono namespace under std> using> std::chrono;> > auto> start = high_performance_clock::now();> > // Do Something> auto> stop = high_performance_clock::now();> auto> duration duration_cast(stop - start);> |
>
>
단일 식별자를 가져오기 위해 명령문을 사용할 수도 있습니다. std::cout만 가져오려면 다음을 사용할 수 있습니다.
using std::cout;>
여전히 전체 네임스페이스를 가져오는 경우 전역 범위가 아닌 함수 또는 제한된 범위 내에서 가져오도록 하세요.
함수 정의 또는 클래스, 구조체 정의 내에서 using 네임스페이스 std 문을 사용합니다. 그렇게 하면 네임스페이스 정의가 로컬 범위로 가져오고 최소한 오류가 발생할 경우 발생할 수 있는 위치를 알 수 있습니다.
CPP
#include> > // Avoid this> using> namespace> std;> > void> foo()> {> >// Inside function> >// Use the import statement inside limited scope> >using> namespace> std;> > >// Proceed with function> }> |
>
>
결론.
네임스페이스에서 식별자에 액세스하는 대체 방법을 논의했습니다. 어떤 경우에도 전체 네임스페이스를 소스 코드로 가져오지 마십시오.
좋은 코딩 방법을 배우고 개발하는 데는 어느 정도 시간이 걸릴 수 있지만 일반적으로 장기적으로는 효과가 있습니다. 깨끗하고 모호하지 않으며 오류 없는 강력한 코드를 작성하는 것은 모든 프로그래밍 개발자의 의도여야 합니다.