2011-04-22 4 views
3

에서 함수의 체인 호출 : Baz()을 감안할 때 다른 클래스 상속 수준

class Foo { 
public: 
    void Method1(); 
} 
class Bar extends Foo { 
public: 
    Bar* Method2(); 
} 
class Baz extends Bar { 
public: 
    Baz* Method3(); 
} 

그래서,

someObject *b = new Baz(); 
b->Method3()->Method2()->Method1(); 

이 작동하는 것은, BarMethod1() 포함, Method2()을 포함한 모든 방법을 포함;

는하지만, 형식을 반환하기 때문에 이것은 좋은 생각이 될 것으로 보인다 - 최초의 상속 수준에서 Method1() 간단하게 액세스 할 때 더 복잡한 호출하기 전에 Method3(), 이 한 줄에 호출을 유지하는 데 ..

b->Method1()->Method2()->Method(3); // will not work? 

또한, 누군가 try.. catch.. throwMethod's에 넣으면 다음 값을 잘못 호출하지 않고 체인을 종료하는 경우가 있습니다. 사실입니까?

그래서 C++에서 메서드 체이닝을 올바르게 구현하는 방법은 무엇입니까?

+4

이 유효 C++ 구문이 방법에 의해되지 않습니다 : 구문 오류에서 당신이 TemplateMethod를 호출 할 때 당신은 C++

struct Base { virtual Base* One() { return this; }; void TemplateMethod() { this->One(); } }; struct Derived : public Base { virtual Base* One() { /* do something */ return Base::One(); } }; 

새로운 것을 수집합니다. – GManNickG

+1

** [CRTP] (http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)를 조회하고 울음. ** 가상의 메소드가없는 동일한 기능을 제공하지만 구현하기가 훨씬 복잡합니다. – CodeAngry

+0

@ CodeAngry 어떻게 든 그것은 habrahabr.ru 같은 날에 당신이 여기에 언급 했었습니다 .. –

답변

2

이것이 바로 가상 방법입니다.

int main() 
{ 

     Base* d = new Derived(); 
     d->TemplateMethod(); // *will* call Derived::One() because it's virtual 

     delete d; 

     return 0; 
} 
+1

'Derived :: One'은 공분산 반환 유형에 대한 C++의 지원으로 인해 OP가 찾고있는 것일 수있는 'Base *'가 아닌'Derived * '를 반환 할 수 있습니다. – ildjarn

+1

나는 의심 스럽습니다. : OP는 이들을 연결하는 것에 대해 걱정했습니다 (실제 다형성이 걱정이었습니다). 또한, 당신은'Base :: One()'을 반환 할 수 없었습니다 (without ... erm ... casting - 추한) – sehe