문제

은 무엇의 장점과 단점을 중첩하여 공 C++클래스와 열거?예를 들어,당신은 라는 클래스 printer, 고 이래도 저장에 대한 정보를 산출 쟁반,당신은 수 있다:

class printer
{
public:
    std::string name_;

    enum TYPE
    {
        TYPE_LOCAL,
        TYPE_NETWORK,
    };

    class output_tray
    {
        ...
    };
    ...
};

printer prn;
printer::TYPE type;
printer::output_tray tray;

또:

class printer
{
public:
    std::string name_;
    ...
};

enum PRINTER_TYPE
{
    PRINTER_TYPE_LOCAL,
    PRINTER_TYPE_NETWORK,
};

class output_tray
{
    ...
};

printer prn;
PRINTER_TYPE type;
output_tray tray;

나는 이득을 볼 수 있는 중첩의 개인 열거형/클래스,하지만 그것을 대중들,이 사무실은 분할 것 이상의 스타일을 선택입니다.

그래서,어떤 당신이 선호하는 이유는?

도움이 되었습니까?

해결책

중첩된 클래스

여러 가지가 있는 부작용 클래스에는 중첩된 내부 클래스는 일반적으로 고려한 결함(하지 않을 경우 순수한 antipatterns).

자 상상해 다음과 같은 코드:

class A
{
   public :
      class B { /* etc. */ } ;

   // etc.
} ;

또:

class A
{
   public :
      class B ;

   // etc.
} ;

class A::B
{
   public :

   // etc.
} ;

그래서:

  • Privilegied 액세스: A::B privilegied 스의 모든 구성원(방식,변수,기호,etc.), 는 약화 캡슐화
  • 의 범위는 후보에 대한 상징 조회: 코드가 내부에서 볼 수 B 모든 기호에서 가능한에 대한 후보자 상징 조회 혼동할 수 있는 코드
  • 앞으로 선언: 방법은 없을 전향을 선언::B 지 않고 주기 전체의 선언
  • 확장성: 그것은 불가능을 추가하는 또 다른 클래스::C 지 않는 한 당신은 당신의 소유자
  • 코드 상세 정보: 퍼팅 클래스 클래스로 만 헤더 크다.할 수 있습이 별도로 여러 선언을 하지만 아무 방법이 사용하는 네임스페이스-다음과 같 별칭,수입 또는 using.

결론적으로,지 않으면 예외가(예:중첩된 클래스는 친밀한 부분의 중첩 클래스...심지어 다음과...),전혀 보이지 않는 점에서 중첩된 클래스에서는 정상적인 코드로 결함 outweights 에 의해 크기의 감지 장점이 있습니다.

또한,그것은 냄새로 서투른 시도하는 시뮬레이션 namespacing 없이 사용하여 C++을 사용하는 네임스페이스입니다.

에 pro-측면,당신은 분리가 이 코드,그리고 개인의 경우,그것을 사용할 수 없지만"외부"에서는 클래스...

중첩된 열거형

장점:모든 것입니다.

Con:아무것도 아니다.

사실은 열거한 항목은 오염 글로벌 범위:

// collision
enum Value { empty = 7, undefined, defined } ;
enum Glass { empty = 42, half, full } ;

// empty is from Value or Glass?

Ony 여 각 enum 에서 다른 네임스페이스/클래스를 사용하면 이를 방지하기 위해 충돌:

namespace Value { enum type { empty = 7, undefined, defined } ; }
namespace Glass { enum type { empty = 42, half, full } ; }

// Value::type e = Value::empty ;
// Glass::type f = Glass::empty ;

참고는 C++0x 정의 클래스 enum:

enum class Value { empty, undefined, defined } ;
enum class Glass { empty, half, full } ;

// Value e = Value::empty ;
// Glass f = Glass::empty ;

정확하게 이런 종류의 문제입니다.

다른 팁

대규모 프로젝트에 큰 도움이 될 수있는 하나의 사기는 중첩 된 클래스 나 열거에 대한 선언을하는 것이 불가능하다는 것입니다.

독립 클래스의 구현과 함께 일하는 것 외에도 종속 클래스를 사용하지 않을 경우 내 의견으로는 중첩 클래스가 괜찮습니다.

"내부"클래스를 그 자체로 객체로 사용하고 싶을 때, 사물이 약간의 맨키를 얻기 시작하고 추출기/삽입기 루틴을 작성해야합니다. 예쁜 상황이 아닙니다.

이런 식으로 서로 관련이있는 것들과 같은 그룹을 위해 클래스 대신 네임 스페이스를 사용해야하는 것 같습니다. 중첩 클래스를 수행 할 때 볼 수있는 하나의 사기는 섹션을 검색 할 때 grok하기 어려울 수있는 정말 큰 소스 파일로 끝나는 것입니다.

중첩 된 공개 C ++ 클래스를 사용하는 장단점은 없습니다. 사실 만 있습니다. 이러한 사실은 C ++ 표준에 의해 의무화됩니다. 중첩 된 공개 C ++ 클래스에 대한 사실이 프로 또는 사기인지 여부는 해결하려는 특정 문제에 달려 있습니다. 당신이 주신 예는 중첩 클래스가 적절한 지 아닌지에 대한 판단을 허용하지 않습니다.

중첩 된 클래스에 대한 한 가지 사실은 그들이 속한 클래스의 모든 구성원에게 특권을 얻는다는 것입니다. 중첩 클래스에 그러한 액세스가 필요하지 않은 경우 이것은 사기입니다. 그러나 중첩 클래스에 그러한 액세스가 필요하지 않으면 중첩 클래스로 선언되어서는 안됩니다. 수업 일 때 상황이 있습니다 다른 클래스에 대한 특권 액세스 권한을 부여하려고합니다 . 이 문제에는 세 가지 해결책이 있습니다

  1. 만들다 친구
  2. 만들다 중첩 클래스
  3. 방법과 속성을 만들어냅니다 필요, 공개 회원 .

이 상황에서는 캡슐화를 위반하는 것이 #3입니다. 그의 친구들과 그의 중첩 된 수업을 통제하지만 공개 방법을 부르거나 공개 속성에 액세스하는 수업은 아닙니다.

중첩 클래스에 대한 또 다른 사실은 다른 클래스를 추가하는 것이 불가능하다는 것입니다. A :: c 중첩 된 클래스로 당신이 소유자가 아니라면 . 그러나 중첩 클래스에는 특권이있는 액세스 권한이 있기 때문에 이것은 완벽하게 합리적입니다. 추가 할 수 있다면 A :: c 중첩 된 클래스로 , 그 다음에 A :: c 트릭 할 수 있습니다 특권 정보에 대한 액세스 권한을 부여하는 데; 그리고 당신은 캡슐화를 위반합니다. 기본적으로와 동일합니다 friend 선언 : friend 선언은 당신에게 친구가 다른 사람으로부터 숨어 있다는 특별한 특권을 부여하지 않습니다. 친구가 친구가 아닌 사람들로부터 숨어있는 정보에 액세스 할 수 있습니다. C ++에서, 누군가를 친구라고 부르는 것은 이기적인 행동이 아니라 이타적인 행동입니다. 클래스가 중첩 클래스가되도록 허용하는 것도 마찬가지입니다.

중첩 된 공공 수업에 대한 다른 사실 :

  • A의 범위는 B의 심볼 조회 후보입니다.: 당신이 이것을 원하지 않는다면, 만드십시오 친구 중첩 된 클래스 대신. 그러나 정확히 이런 종류의 기호 조회를 원하는 경우가 있습니다.
  • A :: b 앞으로 선언 할 수 없습니다: 그리고 A :: b 단단히 결합됩니다. 사용할 수 있습니다 A :: b 알지 못하고 이 사실 만 숨길 것입니다.

이를 요약하면 : 도구가 귀하의 요구에 맞지 않으면 도구를 비난하지 마십시오. 도구를 사용한 것에 대해 자신을 비난하십시오. 다른 사람들은 도구가 완벽한 다른 문제가있을 수 있습니다.

Paercebal은 중첩 된 열거에 대해 내가 말할 모든 것을 말했다.

WRT 중첩 클래스 인 저의 일반적이고 거의 유일한 유스 케이스는 특정 유형의 리소스를 조작하는 클래스가있을 때이며 해당 리소스에 특정한 것을 나타내는 데이터 클래스가 필요합니다. 귀하의 경우, Output_tray는 좋은 예일 수 있지만, 클래스가 포함 된 클래스 외부에서 호출 될 방법이 있거나 주로 데이터 클래스 이상인 경우 일반적으로 중첩 클래스를 사용하지 않습니다. 나는 또한 포함 된 클래스가 포함 된 클래스 밖에서 직접 참조되지 않는 한 일반적으로 데이터 클래스를 중첩하지 않습니다.

예를 들어, Printer_Manipulator 클래스가있는 경우 프린터 조작 오류에 대한 클래스가 포함되어있을 수 있지만 프린터 자체는 포함되지 않은 클래스입니다.

도움이 되었기를 바랍니다. :)

나중에 중첩 된 클래스를 최상위 수준으로 홍보 할 수는 있지만 기존 코드를 깨뜨리지 않고는 반대를 수행하지 못할 수 있습니다. 따라서 제 조언은 먼저 중첩 클래스로 만들고 문제가되기 시작하면 다음 버전에서 최상위 클래스로 만드십시오.

나에게 외부에있는 큰 사기는 그것이 글로벌 네임 스페이스의 일부가된다는 것입니다. 열거 또는 관련 클래스가 실제로 들어있는 클래스에만 적용되는 경우 의미가 있습니다. 따라서 프린터 케이스에서는 프린터가 포함 된 모든 것이 Enum Printer_type에 완전히 액세스 할 수있는 것에 대해 알게 될 것입니다. 나는 내부 클래스를 사용한 적이 있다고 말할 수는 없지만 열거적인 경우, 이것은 내부를 유지하는 것이 더 논리적으로 보입니다. 다른 포스터가 지적했듯이, 글로벌 네임 스페이스를 막는 것은 실제로 나쁜 일이 될 수 있기 때문에 네임 스페이스를 사용하여 유사한 항목을 그룹화하는 것이 좋습니다. 나는 이전에 방대 한 프로젝트를 수행했으며 글로벌 네임 스페이스에서 자동 완료 목록을 가져 오는 데 20 분이 걸립니다. 내 의견으로는 중첩 된 열거와 네임 스패닝 클래스/스트러크가 아마도 가장 깨끗한 접근법 일 것입니다.

나는 수업에 열거를 포함시키기 위해 옹호하는 게시물에 동의하지만 그렇게하지 않는 것이 더 의미가있는 경우가 있습니다 (그러나 적어도 네임 스페이스에 넣으십시오). 여러 클래스가 다른 클래스 내에서 정의 된 열거를 사용하는 경우 해당 클래스는 다른 콘크리트 클래스 (열거를 소유 한)에 직접 의존합니다. 이 클래스는 그 열거와 다른 책임에 책임이 있기 때문에 확실히 설계 결함을 나타냅니다.

따라서 다른 코드가 해당 콘크리트 클래스와 직접 인터페이스하기 위해 해당 열거를 사용하는 경우 클래스에 열거를 포함시킵니다. 그렇지 않으면 네임 스페이스와 같은 열거를 유지할 수있는 더 나은 장소를 찾으십시오.

열거를 클래스 나 네임 스페이스에 넣으면 Intellisense는 열거 이름을 기억하려고 할 때 지침을 제공 할 수 있습니다. 확실히 작은 것, 때로는 작은 것이 중요합니다.

Visual Studio2008 하지 않는 것을 제공할 수 있서는 사용 중첩된 클래스고,그래서 난로 전환 PIMPL 관용구에서 대부분의 경우는 내가 가지고하는 데 사용되는 중첩된 클래스입니다.나는 항상 열거나 클래스에 사용되는 경우에만 해당 클래스로,또는 외부에서 클래스에서는 동일한 네임스페이스 클래스 때 하나 이상의 클래스를 사용하여 열거.

중첩 된 클래스를위한 사기를 볼 수 있습니다. 일반 프로그래밍을 더 잘 사용할 수 있습니다.

작은 클래스가 큰 클래스 밖에서 정의 된 경우, 큰 클래스 A 클래스 템플릿을 만들고 미래에 큰 클래스와 함께 필요한 "작은"클래스를 사용할 수 있습니다.

일반 프로그래밍은 강력한 도구이며, IMHO는 확장 가능한 프로그램을 개발할 때 명심해야합니다. 이상한, 아무도이 점을 언급하지 않았습니다.

내가 아직 부딪친 중첩 클래스의 문제는 C ++가 중첩 클래스 기능에서 둘러싸는 클래스의 대상을 언급하지 못한다는 것입니다. 우리는 "enclosing :: this"라고 말할 수 없습니다.

(하지만 아마도 방법이 있습니까?)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top