2015-09-22 54 views
0

如果有誰能夠告訴我這到底是怎麼回事我會很感激的論點純虛函數:說我聲明如下相同類別

class Base { 
public: 
    virtual void member(Base b) = 0; 
}; 

這給下面的編譯器錯誤:

pvf.cpp:3:18: error: cannot declare parameter ‘b’ to be of abstract type ‘Base’ 
    virtual void member(Base b) = 0; 
      ^
pvf.cpp:1:7: note: because the following virtual functions are pure within ‘Base’: 
    class Base { 
^
pvf.cpp:3:18: note:  virtual void Base::member(Base) 
    virtual void member(Base b) = 0; 

但是,如果我通過引用傳遞,它編譯沒有問題:

class Base { 
public: 
    virtual void member(Base& b) = 0; 
}; 

此外,我想李柯在派生類中實現()成員作爲

class Base { 
public: 
virtual void member(Base& b) = 0; 
}; 

class Derived : public Base { 
public: 
    void member(Derived& d) {}; 
}; 

int main() { 
    Derived d; 
} 

不過,(明顯?)我得到

pvf.cpp: In function ‘int main()’: 
pvf.cpp:12:14: error: cannot declare variable ‘d’ to be of abstract type ‘Derived’ 
    Derived d; 
    ^
pvf.cpp:6:8: note: because the following virtual functions are pure within ‘Derived’: 
    class Derived : public Base { 
    ^
pvf.cpp:3:15: note:  virtual void Base::member(Base&) 
    virtual void member(Base& b) = 0; 
+1

如果你聲明'member(Base b)'(沒有引用),這意味着每次有人調用'member'時,參數都會被傳值並被複制(如果傳入的對象實際上是一個派生的',它會在複製過程中得到*切片*)。 – Cameron

+0

是的。如預期的那樣。使用'Base&'。你有什麼問題? –

回答

2

你的第一個功能

virtual void member(Base b) = 0; 

通過採取Base類的參數值,其要求將的實例傳遞給它。但由於Base是一個抽象類(因爲它包含一個純虛函數),所以它不能被實例化,因此你不能創建一個Base的實例傳遞給它!這是你第一次錯誤的原因。

在你的第二個情況下,在派生類中聲明瞭一個函數

void member(Derived& d) {}; 

,你可能會認爲重寫了基類的虛函數

virtual void member(Base& b) = 0; 

但它沒有(這其實隱藏它 - 見Why does a virtual function get hidden?對此有解釋),所以Derived仍然是抽象類,因爲你有而不是提供了在基類中的純虛函數的實現。因爲這個原因,Derived也不能實例化。無法爲基類純虛函數提供實現的派生類將保持抽象,就像基類一樣。

+0

謝謝!我試圖實現的是一個基類,它強制所有的派生類實現一個傳值方法Derived :: member(Derived d)。我接近這一切都錯了嗎? – user32849

+1

@user:我們必須知道更多關於您的特定應用程序以確定它是否「錯誤」,但肯定可以使用奇怪的循環模板模式(CRTP):'template class Base {public :virtual void member(TDerived b)= 0; };派生類:基地 {...};'。這可能不是你真正想要的,雖然... – Cameron

+0

我正在寫一些統計軟件,我希望能夠在通用代碼中執行類似Distribution :: sample(Parameters p)的操作,但是我會喜歡能夠在運行時插入分佈類型,例如Gaussian :: sample(NormalParam p)等,其中Gaussian從Distribution派生,NormalParam派生自Parameters,我想斷言所有分佈執行:: sample()。一個觀察類需要我將同一個類的一個對象傳遞給一個方法。價值傳遞僅僅是我偶然發現的一種好奇心,而不是一種要求 - 一直在努力學習;-) – user32849