2016-12-26 45 views
3

我有一個頭冷,所以它可能是我只是太擁塞瞭解這裏發生了什麼,但我不明白如何不編譯?C++函數重載(瞭解爲什麼這種情況是不明確的)

#include <string> 
#include <iostream> 

class Base { 

public: 
    virtual void foo(const std::string & data) { 
     foo(data.data(), data.size()); 
    } 
    virtual void foo(const void * bytes, int size) = 0; 

}; 

class Derived : public Base{ 

public: 
    virtual void foo(const void * bytes, int size) { 
     std::cout << "Num Bytes: " << size << std::endl; 
    } 
}; 

int main() { 
    Derived x; 
    std::string blah = "Hello"; 
    x.foo(blah); 
    return 0; 
} 

我得到的錯誤是:

./foo.cpp: In function ‘int main()’: 
./foo.cpp:25:15: error: no matching function for call to ‘Derived::foo(std::__cxx11::string&)’ 
    x.foo(blah); 
      ^
./foo.cpp:17:18: note: candidate: virtual void Derived::foo(const void*, int) 
    virtual void foo(const void * bytes, int size) { 
       ^
./foo.cpp:17:18: note: candidate expects 2 arguments, 1 provided 

如果我重新命名的foofooString第一個實例,然後一切工作如此看來的foo二審以某種方式隱藏第一。但是,鑑於第二種情況有兩個參數而不是一個,我無法弄清楚它將如何模糊。

更新:它也能正常工作,沒有繼承(如果它是一個類),所以我懷疑我誤解了一些繼承規則。

+3

http://stackoverflow.com/questions/4146499/why-does-a-virtual-function-get-hidden –

+0

@latedeveloper謝謝,這很好地解釋它。 – Pace

+0

工作'x.Base :: foo(blah);' –

回答

1

你裏面Derivedvirtual void foo(const void * bytes, int size)函數需要兩個參數,但是從main調用這個函數x.foo(blah);你逝去的只有一個參數blah

您需要將兩個參數傳遞給函數調用,因爲foo函數在Derived類中預期。

另外,如果你想調用Base類的foo功能,嘗試x.Base::foo(blah);

1

的問題與您的代碼是,該功能是含糊!相反,問題是Derived中的覆蓋實際上隱藏了基類函數!如果你想避免這個隱藏,你可以使提供了using -declaration基類版本:

class Derived: public Base { 
    // ... 
public: 
    using Base::foo; 
    void foo(void const* bytes, int size) override { 
     // ... 
    } 
}; 

另外,您可以使用資格在調用點顯式調用基類的功能

x.Base::foo(blah); 

爲了避免具有派生類中做一些特殊的需要時,他們重寫virtual功能你是最好關閉使用具有的方針virtual功能是protected和具有public功能委託給這些(這種方式一致地用於virtual功能在標準C++庫),例如:

class Base { 
protected: 
    virtual void do_foo(std::string const& s) { 
     this->foo(s.c_str(), s.size()); 
    } 
    virtual void do_foo(void const* bytes, int size) = 0; 
public: 
    void foo(std::string const& s) { this->do_foo(s); } 
    void foo(void const* bytes, int size) { this->do_foo(bytes, size); } 
}; 

...然後在派生類適當地覆蓋do_foo()

相關問題