2011-04-22 108 views
3

的功能鏈考慮:調用不同類的繼承層次

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(); 

這工作,因爲Baz()包含了所有方法,包括Method2()Bar包含Method1();

但是,由於返回類型,這似乎是一個糟糕的主意 - 在訪問第一個繼承級別簡單Method1()時調用複雜的前Method3()並且必須保持這種調用單行 ..

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

另外,有人告訴我,將try.. catch.. throw放在其中一個Method's之內有時會退出鏈條,而不會以錯誤的值調用下一個方法。這是真的?

那麼如何在C++中正確實現方法鏈?

+4

這不是有效的C++語法,順便說一句。 – GManNickG 2011-04-22 22:11:19

+1

**查找[CRTP](http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)和哭泣。**它提供的功能與「虛擬」方法相同,但實現起來更復雜。 – CodeAngry 2014-02-06 12:00:47

+0

@CodeAngry不知何故它是在habrahabr.ru同一天,你在這裏提到它.. – 2014-02-08 17:21:55

回答

2

這就是虛擬方法的用途。從語法錯誤我瞭解,你是新的C++

struct Base 
{ 
    virtual Base* One() { return this; }; 
    void TemplateMethod() { this->One(); } 
}; 

struct Derived : public Base 
{ 
    virtual Base* One() { /* do something */ return Base::One(); } 
}; 

當你調用TemplateMethod:

int main() 
{ 

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

     delete d; 

     return 0; 
} 
+1

請注意,由於C++支持協變返回類型,所以'Derived :: One'可以返回一個Derived *'而不是'Base *',這可能是OP正在尋找的東西...... – ildjarn 2011-04-22 22:13:42

+1

我懷疑它:OP是擔心,而是關於鏈接這些(所以實際的多態性是擔心)。另外,在這種情況下你不能返回'Base :: One()'(沒有... erm ...鑄造 - 醜陋) – sehe 2011-04-22 22:17:15