C ++ 네임 스페이스 조언
저는 C ++ 네임 스페이스 (C # 배경에서 유래)를 스스로 가르치고 있으며 C ++가 대부분의 다른 언어보다 더 나은 기능을 수행하더라도 중첩 네임 스페이스는 그중 하나가 아니라고 생각하기 시작했습니다!
일부 중첩 네임 스페이스를 선언하려면 다음을 수행해야한다고 생각하는 것이 맞습니까?
namespace tier1
{
namespace tier2
{
namespace tier3
{
/* then start your normal code nesting */
}
}
}
반대 :
namespace tier1::tier2::tier3
{
}
C #으로?
앞으로 선언해야 할 때 이것은 훨씬 더 치명적입니다.
namespace tier1
{
namespace tier2
{
namespace forward_declared_namespace
{
myType myVar; // forward declare
}
namespace tier3
{
/* then start your normal code nesting */
class myClass
{
forward_declared_namespace::myType myMember;
}
}
}
}
내가 개발하는 일반적인 시스템은 다음으로 구성됩니다.
MyCompany::MySolution::MyProject::System::[PossibleSections]::Type
이것이 C ++ 예제에서 네임 스페이스를 많이 사용하지 않는 이유입니까? 아니면 일반적으로 단일 (중첩되지 않은) 네임 스페이스 만?
최신 정보
관심있는 사람이라면 이것이 제가이 문제를 해결 한 방법입니다.
C ++ 네임 스페이스는 디자인 메커니즘이 아닙니다. 단순히 이름 충돌을 방지하기위한 것입니다. 99.99 %의 상황에서 중첩 된 네임 스페이스를 사용하고 싶지 않거나 사용할 필요가 없습니다.
C ++에서 네임 스페이스를 올바르게 사용하는 좋은 예는 C ++ 표준 라이브러리입니다. 이 상당히 큰 라이브러리의 모든 것은 std 라는 단일 네임 스페이스에 배치됩니다. 라이브러리를 I / O 하위 네임 스페이스, 수학 하위 네임 스페이스, 컨테이너 하위 네임 스페이스로 분리 할 필요가 없습니다. 기타
C ++ 모델링을위한 기본 도구는 네임 스페이스가 아니라 클래스 (그리고 어느 정도는 템플릿)입니다. 중첩이 필요하다고 생각되면 네임 스페이스에 비해 다음과 같은 이점이있는 중첩 클래스 사용을 고려해야합니다.
- 그들은 방법이있다
- 액세스를 제어 할 수 있습니다.
- 다시 열 수 없습니다.
이러한 사항을 고려한 후에도 여전히 중첩 된 네임 스페이스를 사용하려면 그렇게해야합니다. 이러한 방식으로 사용하는 데 기술적으로 잘못된 것은 없습니다.
C ++ 네임 스페이스는 이전 제품에 비해 크게 향상되었습니다 (즉, 네임 스페이스가 전혀 없음). C # 네임 스페이스는 개념을 확장하고 실행했습니다. 네임 스페이스를 단순한 평면 구조로 유지하는 것이 좋습니다.
편집 당신은 내가 여기에 설명했던 짧은 다름으로 인해 조언합니까?
간단히 "예". C ++ 네임 스페이스는 논리 및 라이브러리를 C #에서와 같이 분할하는 데 도움이되도록 설계되지 않았습니다.
C ++ 네임 스페이스의 목적은 C 개발자가 동일한 함수 이름을 내보내는 두 개의 타사 라이브러리를 사용할 때 이름 충돌이 발생하는 실제 문제를 막는 것입니다. C 개발자에게는 다양한 해결 방법이 있었지만 심각한 고통이 될 수 있습니다.
아이디어는 STL 등에 std::
네임 스페이스 가 있고 , "XYZ Corp"에서 제공하는 libs에는 xyz::
네임 스페이스 가 있고 , "ABC corp"에서 작업하면 모든 항목을 단일 abc::
네임 스페이스 에 넣는 것 입니다.
앞으로 선언 할 때 내가하는 일은 다음과 같습니다.
namespace abc { namespace sub { namespace subsub { class MyClass; }}}
내 앞으로 선언은 한 줄로 축소됩니다. 포워드 선언의 가독성은 나머지 코드의 가독성에 대한 대가로 희생됩니다. 그리고 정의를 위해 들여 쓰기를 사용하지 않습니다.
namespace abc {
namespace sub {
namespace subsub {
class MyClass
{
public:
MyClass();
void normalIntendationsHere() const;
};
}
}
}
이 스타일을 사용하려면 처음에는 약간의 규율이 필요하지만 나에게 가장 좋은 타협점입니다.
약간의 도움으로, 경우에 따라 다음을 수행 할 수 있습니다.
namespace foo = A::B::C::D;
그런 다음 A :: B :: C :: D를 foo로 참조하십시오. 그러나 일부 경우에만.
들여 쓰기를 건너 뛸 수 있습니다. 나는 자주 쓴다
namespace myLib { namespace details {
/* source code */
} } /* myLib::details */
C ++ 소스 코드는 바이너리에 남아있는 C # / Java와 달리 결국 바이너리로 컴파일됩니다. 따라서 네임 스페이스는 변수 이름 충돌에 대한 훌륭한 솔루션을 제공합니다. 클래스 계층 구조용이 아닙니다.
나는 종종 코드에 하나 또는 두 개의 네임 스페이스 수준을 유지합니다.
그 이유가 없기 때문에 우선 네임 스페이스 들여 쓰기를 피할 수 있습니다.
예제에서 네임 스페이스를 사용하면 네임 스페이스 성능이 표시되지 않습니다. 그리고 저에 대한 그들의 힘은 도메인 영역을 서로 나누는 것입니다. 유틸리티 클래스와 비즈니스 클래스를 나눕니다.
하나의 .h 파일에서 서로 다른 네임 스페이스 계층을 혼합하지 마십시오. 네임 스페이스는 함수 선언 인터페이스에 대한 일종의 추가 주석입니다. 네임 스페이스와 클래스 이름을 보면 많은 것을 설명 할 수 있습니다.
namespace product
{
namespace DAO
{
class Entity
{
};
이와 같이 C # 네임 스페이스를 모방 할 수 있음을 발견했습니다.
namespace ABC_Maths{
class POINT2{};
class Complex{};
}
namespace ABC_Maths_Conversion{
ABC_MATHS::Complex ComplexFromPOINT2(ABC_MATHS::POINT2)
{return new ABC_MATHS::Complex();}
ABC_MATHS::POINT4 POINT2FromComplex(ABC_MATHS::COMPLEX)
{return new ABC_MATHS::POINT2();}
}
namespace ABC
{
}
그러나 코드는 그다지 깔끔하지 않은 것 같습니다. 그리고 나는 오랫동안 사용을 기대할 것입니다
다음과 같은 클래스에 많은 기능을 중첩하는 것이 좋습니다.
namespace ABC{
class Maths{
public:
class POINT2{};
class Complex:POINT2{};
class Conversion{
public:
static Maths.Complex ComplexFromPOINT2(MATHS.POINT2 p)
{return new MATHS.Complex();}
static MATHS.POINT2 POINT2FromComplex(MATHS.COMPLEX p)
{return new ABC::MATHS.POINT2();}// Can reference via the namespace if needed
} /*end ABC namespace*/
그리고 그것은 여전히 약간 긴 바람입니다. 하지만 약간 OO 느낌이 듭니다.
그리고 그것이 어떻게 가장 잘 된 것처럼 보이는지 들었습니다.
namespace ABC
{
class POINT2{};
class Complex:POINT2{};
Complex ComplexFromPOINT2(POINT2 p){return new Complex();}
POINT2 POINT2FromComplex(Complex){return new POINT2();}
}
사용법이 어떻게 보일지 듣습니다.
int main()
{
ABC_Maths::Complex p = ABC_Maths_Conversion::ComplexFromPOINT2(new ABC_MATHS::POINT2());
// or THE CLASS WAY
ABC.Maths.Complex p = ABC.Maths.Conversion.ComplexFromPOINT2(new ABC.Maths.POINT2());
// or if in/using the ABC namespace
Maths.Complex p = Maths.Conversion.ComplexFromPOINT2(new Maths.POINT2());
// and in the final case
ABC::Complex p = ABC::ComplexFromPOINT2(new ABC::POINT2());
}
내가 C # 에서처럼 C ++ 네임 스페이스를 사용하지 않은 이유를 알아내는 것은 흥미로 웠습니다. 너무 오래 걸리고 C # 네임 스페이스와 같은 방식으로 작동하지 않습니다.
the best use for namespaces in c++ is to stop say my super cout function (that dings every time its called) from getting mixed up with the std::cout function (which is far less impressive).
Just because c# and c++ have namespaces, it doesn't mean that namespace means the same thing. they are different but similar. The idea for c# namespaces must have come from c++ namespaces. somebody must have seen what a similar but different thing could do, and didn't have enough imagination power left to give it its own original name like "ClassPath" which would kind of make more sense as its a path to classes rather than for providing naming spaces where each space can have the same names
I hope this helps someone
I forgot to say That all of these ways are valid, and moderate use of the first two can be incorporated into the the third to create a library that makes sense ie(not great example)
_INT::POINT2{}
and
_DOUBLE::POINT2{}
so you can change the precision level by using
#define PREC _DOUBLE
// or #define PREC _INT
and then creating an instance of PREC::POINT2 for double precision POINT2
That is not an easy thing to do with c# or java namespaces
obviously that's just one example. Think about how the usage read.
You're over-using them (and you'll get nothing in return).
I sometimes declare deep namespaces as a couple of macros in a separate header
namespace.h
#define NAMESPACE_TIER1_TIER2_TIER3 \
namespace tier1 { \
namespace tier2 { \
namespace tier3 {
#define END_NAMESPACE_TIER1_TIER2_TIER3 }}}
To use it somewhere else:
anotherfile.h
#include "./namespace.h"
NAMESPACE_TIER1_TIER2_TIER3;
/* Code here */
END_NAMESPACE_TIER1_TIER2_TIER3;
The redundant semicolons after the macro are to avoid extra indentation.
참고URL : https://stackoverflow.com/questions/713698/c-namespaces-advice
'developer tip' 카테고리의 다른 글
yaml에서 연관 배열 목록을 만드는 방법 (0) | 2020.10.26 |
---|---|
RuboCop : 줄이 너무 깁니다. <— 무시하는 방법 (0) | 2020.10.26 |
PHP 경고 : 호출 시간 참조에 의한 전달이 더 이상 사용되지 않습니다. (0) | 2020.10.26 |
moment.js isValid 함수가 제대로 작동하지 않습니다. (0) | 2020.10.26 |
컨트롤러별로 다른 컨트롤러의 부분보기를 반환하는 방법은 무엇입니까? (0) | 2020.10.26 |