2009-10-13 72 views
0

我有以下結構:C++重載問題

struct A 
{ 
    A(); 
    virtual ~A(); 

    virtual void Foo() =0; 
}; 

struct E; 
struct F; 

struct B: public A 
{ 
    B(); 
    virtual ~B(); 

    virtual void Bar(E*) =0; 
    virtual void Bar(F*) =0; 
}; 

struct C: public B 
{ 
    C(); 
    virtual ~C(); 

    void Bar(E*); 
}; 

struct D: public C 
{ 
    D(); 
    virtual ~D(); 

    void Foo(); 
    void Bar(F*); 
}; 

struct E: public A 
{ 
    E(); 
    virtual ~E(); 

    void Foo(); 
    /* ... */ 
}; 

struct F: public A 
{ 
    F(); 
    virtual ~F(); 

    void Foo(); 
    /* ... */ 
}; 

template <class _Base> 
struct G: public _Base 
{ 
    G(const _Base &b) 
    : _Base(b) 
    {} 

    virtual ~G() 
    {} 

    using _Base::Bar; // doesn't help 
    /* ... */ 
}; 

當我試圖用E *打電話吧()G型<d>的對象上,我得到以下編譯時錯誤:

error: no matching function for call to 'G<D>::Bar(E*&)'

note: candidates are: virtual void D::Bar(F*)

如果我重新命名(虛擬)空欄(F *)的聲明,代碼編譯罰款,按預期工作。

用法:

typedef std::list<E*> EList; 
typedef std::list<F*> FList; 
EList es; 
FList fs; 

G<D> player(D()); 

es.push_back(new E); // times many 
fs.push_back(new F); // times many 

for(EList::iterator i0(es.begin()), i1(es.end()); i0 != i1; ++i0) 
{ 
    player.Bar(*i0); 
} 

for(FList::iterator i0(fs.begin()), i1(fs.end()); i0 != i1; ++i0) 
{ 
    player.Bar(*i0); 
} 

1,什麼是錯的採取不同的參數成員函數多個重載?

2,爲什麼編譯器不能說明它們之間的區別?

+0

原來,問題是超負荷解決,而不是動態調度相關。我已經解決了這個問題。此外,發現這個:http://stackoverflow.com/questions/72010/c-overload-resolution – zyndor 2009-10-14 08:14:06

回答

3

除非您在using聲明中添加,否則只有包含覆蓋率爲Bar的派生類最多的Bar版本纔會用於重載解析。如果你嘗試

struct D:  public C 
{ 
    D(); 
    virtual ~D(); 

    void  Foo(); 
    void  Bar(F*); 
    using C::Bar; 
}; 

那麼它應該工作。

3

從代碼:

  • G延伸DG<D>
  • 你打電話Bar(E*)G - >G並 沒有Bar方法,以便看看基地 類
  • 基類是D
  • D has Bar(F*)但沒有Bar(E*) - > struct E是不同類型的 struct F,所以你得到一個錯誤

要回答你的問題:電子不相關類型F和編譯可以告訴這就是爲什麼你得到的區別一個錯誤。

我不確定哪個Bar添加虛擬,但是如果基類已經聲明Bar爲虛擬的所有擴展它的類都已經有Bar虛擬,所以如果將該單詞(虛擬)添加到擴展類中並不重要。

如果您展示瞭如何實例化對象以及如何對它調用Bar(F *),它將會有所幫助。有運行時決定取決於你如何調用方法和你傳遞的參數。

+1

如果你重寫基類的重載函數的一個版本,並不意味着隱藏其他,你應該使一切可見與使用聲明。 – UncleBens 2009-10-13 21:39:05

+0

增加了一個使用示例並修正了錯誤:E和F不是相關的類型。邏輯:D是-c,C有Bar(E *)。這算不算什麼?通過不在C和D中聲明Bar(E *)和Bar(F *)是虛擬的,我只是想表明他們的行爲不會被/不會被進一步專門化。它們通過指向其超類對象的指針來使用,所以它本身仍然是一個虛擬調用。 – zyndor 2009-10-14 00:08:41