2016-06-23 3 views
0

아래 예제에서는 꽤 일반적인 CRTP 예제 인 두 개의 서로 다른 파생 클래스 인 bar이 있습니다. 기본 클래스는 유형을해야하기 때문에 기본 클래스의 등을 배열/벡터 /을 가질 수처럼은 보이지 않는다다른 CRTP 파생 클래스 메서드를 반복하십시오.

#include <iostream> 

template<typename Derived> 
class Base { 
public: 
    void foo() { 
     static_cast<Derived*>(this)->bar(); 
    } 
}; 

class DerivedA : public Base<DerivedA> { 
public: 
    void bar() { 
     ::std::cout << "A\n"; 
    } 
}; 

class DerivedB : public Base<DerivedB> { 
public: 
    void bar() { 
     ::std::cout << "B\n"; 
    } 
}; 

int main() { 
    DerivedA a; 
    DerivedB b; 
    a.foo(); 
    b.foo(); 
} 

단지 앞으로 일부 bar 방법을 도출하는 방법 foo있다 T이 다른 Base<T>의 라인을 따라

모두 동일한 방법 (이 경우 bar)가 가정 다른 파생 클래스를 반복 할 수 있기위한 virtual없이 협약의 어떤 종류가 있습니까?

답변

2

Boost.Variant를 사용할 수 있습니다. 예를 들어 : 이것은 당신이 (A는 "노조 차별"을 사용하여) 벡터 또는 다른 STL 컨테이너에 이질적인 종류를 저장할 수 있습니다, 당신은 상관없이이를 가지고 있지의 모두에서 특정 함수를 호출 할 수 있습니다

typedef boost::variant<DerivedA, DerivedB> Derived; 

struct BarCaller : public boost::static_visitor<void> { 
    template <class T> 
    void operator()(T& obj) { 
     obj.bar(); 
    } 
}; 

int main() { 
    std::vector<Derived> vec{DerivedA(), DerivedB(), DerivedA()}; 

    BarCaller bar; 
    for (Derived& obj : vec) { 
     obj.apply_visitor(bar); 
    } 
} 

공통 조상 또는 가상 메서드를 사용합니다.

+0

전체 사례를 게시 하시겠습니까? – asimes

+0

전에'boost :: variant'를 사용하지 않았습니다. 더 이상'Base'가없고'DerivedA'와'DerivedB' 만 남아있을 것이라고 추측하고 있습니까? – asimes

+0

@asimes : 좋아, 나는 당신이 당신의 클래스 정의와 결합하면, 완성 된, 실행 가능한 프로그램이되도록 내 대답을 약간 수정했다. 'Base'를 가지고 있건 없건 상관없이 - 내 코드는 어느 쪽이든 작동합니다. –

3

T이 다른 Base<T>의 라인을 따라 유형을해야하기 때문에 기본 클래스의 등을 배열/벡터/수처럼은 보이지 않는다. 그런 당신을 위해 작동하는 경우

당신은 모든 T에 대한 Base<T>의 기본 클래스를 가질 수 있습니다, 다음, 당신은 기본 클래스에 대한 포인터의 목록/벡터/배열을 가질 수 있습니다.

struct BaseOne 
{ 
    virtual void foo() = 0; 
    virtual ~BaseOne() {} 
}; 

template<typename Derived> 
class Base : struct BaseOne { 
public: 
    void foo() { 
     static_cast<Derived*>(this)->bar(); 
    } 
}; 

하고,

int main() { 
    std::vector<BaseOne*> v {new DerivedA, new DerivedB }; 
    for (auto item : v) 
     item->bar(); 

    for (auto item : v) 
     delete item; 
} 

는 모두 동일한 방법 (이 경우 bar)가 가정 다른 파생 클래스를 반복 할 수 있기위한 virtual없이 협약의 어떤 종류가 있습니까?

아니요, 없습니다.

관련 문제