C ++에서 “super”사용 별칭으로 사용할 수 있습니다. Derived(int i,

내 코딩 스타일에는 다음 관용구가 포함됩니다.

class Derived : public Base
{
   public :
      typedef Base super; // note that it could be hidden in
                          // protected/private section, instead

      // Etc.
} ;

이를 통해 생성자에서 “super”를 Base의 별칭으로 사용할 수 있습니다.

Derived(int i, int j)
   : super(i), J(j)
{
}

또는 재정의 된 버전 내의 기본 클래스에서 메서드를 호출 할 때도 :

void Derived::foo()
{
   super::foo() ;

   // ... And then, do something else
}

심지어 체인으로 묶을 수도 있습니다 (그러나 여전히 그 용도를 찾아야합니다).

class DerivedDerived : public Derived
{
   public :
      typedef Derived super; // note that it could be hidden in
                             // protected/private section, instead

      // Etc.
} ;

void DerivedDerived::bar()
{
   super::bar() ; // will call Derived::bar
   super::super::bar ; // will call Base::bar

   // ... And then, do something else
}

어쨌든, “typedef super”의 사용은 예를 들어 Base가 장황하고 /하거나 템플릿 일 때 매우 유용합니다.

사실 super는 C #뿐만 아니라 Java에서도 구현됩니다 (잘못된 경우가 아니라면 “base”라고합니다). 그러나 C ++에는이 키워드가 없습니다.

그래서 내 질문 :

  • 이 타입 정의 사용은 작업 코드에서 보지 못했습니까?
  • typedef super Ok를 사용합니까 (즉, 사용하지 않을 강력한 이유가 있습니까)?
  • “super”가 좋은 것이어야합니까, C ++에서 다소 표준화되어야합니까, 아니면 typedef를 통해 이미 사용하고 있습니까?

편집 : Roddy는 typedef가 비공개이어야한다는 사실을 언급했습니다. 이것은 파생 클래스가 클래스를 다시 선언하지 않으면 사용할 수 없다는 것을 의미합니다. 그러나 그것은 그것이 super :: super chaining을 막을 것이라고 생각합니다 (그러나 누가 울겠습니까?).

편집 2 : “슈퍼”를 대량으로 사용한 지 몇 개월이 지나서 나는 Roddy의 견해에 전적으로 동의합니다. “슈퍼”는 사적이어야합니다. 나는 그의 대답을 두 번 찬성했지만 나는 할 수 없다고 생각합니다.



답변

Bjarne Stroustrup 은 C ++의 Design and Evolution에서 C ++super처음 표준화 될 때 ISO C ++ 표준위원회에서 키워드로 간주 했다고 언급했습니다 .

Dag Bruck는 기본 클래스를 “상 속됨”이라고하며이 확장을 제안했습니다. 이 제안은 다중 상속 문제를 언급했으며 모호한 용도로 플래그를 지정했을 것입니다. Stroustrup조차도 확신했다.

토론 후 Dag Bruck (예, 제안을 한 사람)은 제안이 구현 가능하고 기술적으로 건전하며 주요 결함이 없으며 다중 상속을 처리했다고 썼습니다. 다른 한편으로, 벅에 대한 강타가 충분하지 않았으므로위원회는 더 어려운 문제를 처리해야합니다.

마이클 타이 만 (Michael Tiemann)이 늦게 도착한 후,이 게시물에서 요구 한 것과 같은 기술을 사용하여 typedef의 슈퍼가 잘 작동한다는 것을 보여주었습니다.

따라서, 이것은 아마도 표준화되지 않을 것입니다.

사본이 없으면 Design and Evolution 은 커버 가격으로 가치가 있습니다. 중고 사본은 약 $ 10에 구입할 수 있습니다.


답변

나는 항상 슈퍼보다는 “상속 된”을 사용했습니다. (아마도 델파이 배경으로 인해), 클래스에서 ‘상속 된’이 잘못 생략되었지만 하위 클래스에서 사용하려고 할 때 문제를 피하기 위해 항상 개인용으로 만듭니다 .

class MyClass : public MyBase
{
private:  // Prevents erroneous use by other classes.
  typedef MyBase inherited;
...

새 클래스를 만들기위한 표준 ‘코드 템플릿’에는 typedef가 포함되어 있으므로 실수로 생략 할 기회가 거의 없습니다.

연쇄 “super :: super”제안은 좋은 생각이라고 생각하지 않습니다. 그렇게하는 경우 특정 계층 구조와 매우 밀접하게 연결되어 있으며 변경하면 문제가 발생할 수 있습니다.


답변

이것의 한 가지 문제는 파생 클래스에 대해 super를 재정의하는 것을 잊어 버린 경우 super :: something에 대한 호출은 정상적으로 컴파일되지만 원하는 함수를 호출하지는 않는다는 것입니다.

예를 들면 다음과 같습니다.

class Base
{
public:  virtual void foo() { ... }
};

class Derived: public Base
{
public:
    typedef Base super;
    virtual void foo()
    {
        super::foo();   // call superclass implementation

        // do other stuff
        ...
    }
};

class DerivedAgain: public Derived
{
public:
    virtual void foo()
    {
        // Call superclass function
        super::foo();    // oops, calls Base::foo() rather than Derived::foo()

        ...
    }
};

Martin York이이 답변에 대한 의견에서 지적한 것처럼이 문제는 typedef를 public 또는 protected가 아닌 private로 만들어 제거 할 수 있습니다.


답변

FWIW Microsoft는 컴파일러 에 __super 에 대한 확장을 추가했습니다 .


답변

Super (또는 상속 된)는 매우 좋은 것입니다. Base와 Derived 사이에 다른 상속 계층을 고정해야하는 경우 다음 두 가지만 변경하면됩니다. 1. “class Base : foo”및 2. typedef

내가 올바르게 기억한다면, C ++ 표준위원회는 Michael Tiemann이이 typedef 트릭이 효과가 있다고 지적 할 때까지 이것에 대한 키워드 추가를 고려하고있었습니다.

다중 상속에 관해서는 프로그래머 제어하에 있기 때문에 super1 및 super2 또는 무엇이든 원하는대로 할 수 있습니다.


답변

방금 다른 해결 방법을 찾았습니다. 오늘 날 typedef 접근법에 큰 문제가 있습니다.

  • typedef에는 클래스 이름의 정확한 사본이 필요합니다. 누군가 클래스 이름을 변경했지만 typedef를 변경하지 않으면 문제가 발생합니다.

그래서 나는 매우 간단한 템플릿을 사용하여 더 나은 솔루션을 생각해 냈습니다.

template <class C>
struct MakeAlias : C
{
    typedef C BaseAlias;
};

그래서 지금 대신

class Derived : public Base
{
private:
    typedef Base Super;
};

당신은 가지고

class Derived : public MakeAlias<Base>
{
    // Can refer to Base as BaseAlias here
};

이 경우 BaseAlias비공개가 아니며 다른 개발자에게 경고 해야하는 유형 이름을 선택하여 부주의 한 사용을 방지하려고했습니다.


답변

나는 이것을 전에 본 것을 기억하지 못하지만 언뜻보기에 나는 그것을 좋아한다. Ferruccio가 지적한 바와 같이 MI에서는 잘 작동하지 않지만 MI는 규칙보다 예외이며 유용하기 위해 어디에서나 사용할 수 있어야한다고 말하는 것은 없습니다.