재정의 가능한 메서드에 대한 기본 구현을 제공하려면 어떻게해야합니까?

댄 네스터

Visitor 패턴을 가지고 놀고 있는데 컴파일되는 다음과 같은 코드가 있습니다.

class DerivedVisitee;

class Visitor
{
public:
    void visit(DerivedVisitee &v);
};

class Visitee
{
public:
    virtual void accept(Visitor &v) = 0;
};

class DerivedVisitee : public Visitee
{
public:
    void accept(Visitor &v) { v.visit(*this); }
};

visit모든 자손에 대해 기본 방법 을 제공하고 싶습니다 Visitee. 따라서 다음을 시도했습니다.

class DerivedVisitee;

class Visitor
{
public:
    void visit(DerivedVisitee &v);
};

class Visitee
{
public:
    virtual void accept(Visitor &v) { v.visit(*this); } // added implementation here
};

class DerivedVisitee : public Visitee
{
    // removed overridden method
};

그러나 'void Visitor::visit(DerivedVisitee &)' : cannot convert argument 1 from 'Visitee' to 'DerivedVisitee &'(MSVC) 에서는 컴파일이 실패합니다 . 이런 일이 발생하는 이유와 내가하려는 작업을 수행하는 올바른 방법이 무엇인지 설명해 주시겠습니까?

편집 : 개체에서만 Visitor::visit작업해야합니다 DerivedVisitee. 다른 말로하면 Visitor::visit.NET의 다른 자손에 대해 다른 구현으로 여러 오버로드 된 메서드 를 사용하려고합니다 Visitee.

매튜 엠.

기본적인 대답은 순수 객체 지향 코드에서는 불가능 하다는 것입니다.

본질적으로 방문자 패턴은 visit파생 된 유형으로 전달하는 것이며 , 해당 Visitee유형에서는 알 수 없습니다 (런타임 속성 임).


C ++에는 CRTP 라는 패턴이 있습니다 .

template <typename Derived, typename Base>
class VisiteeHelper: public Base {
public:
    virtual void accept(Visitor& v) override {
        Derived& d = static_cast<Derived&>(*this);
        v.visit(d);
}; // class VisiteeHelper

그리고 다음에서 파생 할 수 있습니다.

// And there we see the "Curiously Recurring" part:
class DerivedVisitee: public VisiteeHelper<DerivedVisitee, Visitee> {
}; // class DerivedVisitee

class MoreDerivedVisitee: public VisiteeHelper<MoreDerivedVisitee, DerivedVisitee> {
}; // MoreDerivedVisitee

단순하지 않은 상용구 또는 스마트 한 (하지만 잠재적으로 혼란스러운) CRTP 솔루션을 선호하는지 여부를 결정하는 것은 귀하에게 달려 있습니다.

개인적으로 accept(const-ness에 오버로딩하여 유형 당 최대 4 개의) 오버로드가 여러 개있는 경우 가 아니면 신경 쓰지 않습니다. accept으로 쓰는 것만큼이나 많은 작업이 필요 하며, 간단하고 즉시 이해할 수 있습니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

SwiftUI 구성에 대한 기본값을 제공하지만 사용자가이를 재정의하도록하려면 어떻게해야합니까?

분류에서Dev

목록에없는 확장에 대한 기본 앱을 설정하려면 어떻게해야합니까?

분류에서Dev

메뉴가 아닌 코드에서 MATLAB 기본 설정을 변경하려면 어떻게해야합니까?

분류에서Dev

Windows 10의 기본 제공 압축 해제 기능을 활성화하려면 어떻게해야합니까?

분류에서Dev

get에 더 많은 기능을 추가하려면 어떻게해야합니까? 및 설정; Xamarin 양식에서 "=>"를 제거하고 각각에 대한 코드 블록으로 대체합니까?

분류에서Dev

구독자에게 반환하기 전에 관찰 가능한 개체를 가로 채서 RxJava에서 수정하려면 어떻게해야합니까?

분류에서Dev

하드 드라이브의 정확한 복구 가능한 사본을 만들려면 어떻게합니까?

분류에서Dev

2D 캔버스에서 확대 / 축소 기능을 구현하려면 어떻게해야합니까?

분류에서Dev

ServiceStack에서 만료 토큰 기반 권한 부여의 추가 계층을 구현하려면 어떻게해야합니까?

분류에서Dev

Xamarin.Forms의 IsPropertyChanged 메서드 내에서 바인딩 가능한 속성의 설정을 확인하려면 어떻게해야합니까?

분류에서Dev

C #에 대한 기본 VS Code 네임 스페이스를 구성하려면 어떻게해야합니까?

분류에서Dev

한 시트에서 인접 값을 가져와 현재 시트의 다른 셀 내용을 기반으로 합산하려면 어떻게해야합니까?

분류에서Dev

람다 식에 정확히 한 번 변수 값을 제공하려면 어떻게해야합니까?

분류에서Dev

로직 레이어에 대한 지원보기를 선택적으로 제공하도록 코드를 구성하려면 어떻게해야합니까?

분류에서Dev

하위 도메인을 기반으로 사용자 정의 가능한 CSS를 설정하려면 어떻게해야합니까?

분류에서Dev

Android Studio에서 데이터 바인딩에 대한 기본값을 설정하려면 어떻게해야합니까?

분류에서Dev

야외 공간에 대한 소유자 권한을 제거하려면 어떻게해야합니까?

분류에서Dev

다시 재생 기능을 구현하려면 어떻게해야합니까?

분류에서Dev

ElasticBeanstalk 애플리케이션에 대한로드 밸런서 및 용량과 같은 구성을 재정의하려면 어떻게해야합니까?

분류에서Dev

숫자에 대해 가능한 모든 제수 곱을 생성하려면 어떻게해야합니까?

분류에서Dev

GridViewItem을 XAML의 DataTemplate 대신 드래그 가능한 개체로 만들려면 어떻게해야합니까?

분류에서Dev

R에서 곡선 맞춤에 대한 특정 값을 제외하려면 어떻게해야합니까?

분류에서Dev

탭 앤 홀드 기능을 구현하려면 어떻게해야합니까?

분류에서Dev

AX 2012에서 특정 기본 계정에 대한 계정 구조를 얻으려면 어떻게해야합니까?

분류에서Dev

재 작성으로 nginx 구성에 기본 인증을 추가하려면 어떻게해야합니까?

분류에서Dev

Courseid 값에 대한 동적 값을 사용하면서 jmeter에서 정규식 추출기를 구성하려면 어떻게해야합니까?

분류에서Dev

"TR"의 CSS 스타일에서 선택한 행을 강조 표시에서 단추 기능을 제외하려면 어떻게해야합니까?

분류에서Dev

인스턴스 메서드를 호출하기 전에 한 줄에 Enum을 기본 형식으로 캐스팅하려면 어떻게해야합니까?

분류에서Dev

Flutter 열의 위젯을 사용 가능한 크기로 축소하려면 어떻게해야합니까?

Related 관련 기사

  1. 1

    SwiftUI 구성에 대한 기본값을 제공하지만 사용자가이를 재정의하도록하려면 어떻게해야합니까?

  2. 2

    목록에없는 확장에 대한 기본 앱을 설정하려면 어떻게해야합니까?

  3. 3

    메뉴가 아닌 코드에서 MATLAB 기본 설정을 변경하려면 어떻게해야합니까?

  4. 4

    Windows 10의 기본 제공 압축 해제 기능을 활성화하려면 어떻게해야합니까?

  5. 5

    get에 더 많은 기능을 추가하려면 어떻게해야합니까? 및 설정; Xamarin 양식에서 "=>"를 제거하고 각각에 대한 코드 블록으로 대체합니까?

  6. 6

    구독자에게 반환하기 전에 관찰 가능한 개체를 가로 채서 RxJava에서 수정하려면 어떻게해야합니까?

  7. 7

    하드 드라이브의 정확한 복구 가능한 사본을 만들려면 어떻게합니까?

  8. 8

    2D 캔버스에서 확대 / 축소 기능을 구현하려면 어떻게해야합니까?

  9. 9

    ServiceStack에서 만료 토큰 기반 권한 부여의 추가 계층을 구현하려면 어떻게해야합니까?

  10. 10

    Xamarin.Forms의 IsPropertyChanged 메서드 내에서 바인딩 가능한 속성의 설정을 확인하려면 어떻게해야합니까?

  11. 11

    C #에 대한 기본 VS Code 네임 스페이스를 구성하려면 어떻게해야합니까?

  12. 12

    한 시트에서 인접 값을 가져와 현재 시트의 다른 셀 내용을 기반으로 합산하려면 어떻게해야합니까?

  13. 13

    람다 식에 정확히 한 번 변수 값을 제공하려면 어떻게해야합니까?

  14. 14

    로직 레이어에 대한 지원보기를 선택적으로 제공하도록 코드를 구성하려면 어떻게해야합니까?

  15. 15

    하위 도메인을 기반으로 사용자 정의 가능한 CSS를 설정하려면 어떻게해야합니까?

  16. 16

    Android Studio에서 데이터 바인딩에 대한 기본값을 설정하려면 어떻게해야합니까?

  17. 17

    야외 공간에 대한 소유자 권한을 제거하려면 어떻게해야합니까?

  18. 18

    다시 재생 기능을 구현하려면 어떻게해야합니까?

  19. 19

    ElasticBeanstalk 애플리케이션에 대한로드 밸런서 및 용량과 같은 구성을 재정의하려면 어떻게해야합니까?

  20. 20

    숫자에 대해 가능한 모든 제수 곱을 생성하려면 어떻게해야합니까?

  21. 21

    GridViewItem을 XAML의 DataTemplate 대신 드래그 가능한 개체로 만들려면 어떻게해야합니까?

  22. 22

    R에서 곡선 맞춤에 대한 특정 값을 제외하려면 어떻게해야합니까?

  23. 23

    탭 앤 홀드 기능을 구현하려면 어떻게해야합니까?

  24. 24

    AX 2012에서 특정 기본 계정에 대한 계정 구조를 얻으려면 어떻게해야합니까?

  25. 25

    재 작성으로 nginx 구성에 기본 인증을 추가하려면 어떻게해야합니까?

  26. 26

    Courseid 값에 대한 동적 값을 사용하면서 jmeter에서 정규식 추출기를 구성하려면 어떻게해야합니까?

  27. 27

    "TR"의 CSS 스타일에서 선택한 행을 강조 표시에서 단추 기능을 제외하려면 어떻게해야합니까?

  28. 28

    인스턴스 메서드를 호출하기 전에 한 줄에 Enum을 기본 형식으로 캐스팅하려면 어떻게해야합니까?

  29. 29

    Flutter 열의 위젯을 사용 가능한 크기로 축소하려면 어떻게해야합니까?

뜨겁다태그

보관