2012-05-05 165 views
1

我正在嘗試使基類定義所有派生類的接口。C++:在非虛函數中使用純虛函數

我想要一個函數,允許讀取該類的配置文件,這是使用boost::property_tree相當順利的工作。我們稱之爲readConfig。 這將不得不在每個派生類中定義,所以我把它變成了純粹的虛擬。

我想超載readConfig函數的基類,其中在基類中的每個重載函數最終調用純虛擬形式,例如:

class Base 
{ 
    // ... 
    void readConfig(string, string);         // read config from file 
    virtual void readConfig(boost::property_tree::ptree, string) =0; // read config from ptree 
} 

void Base::readConfig(string filename, string entry) 
{ 
    boost::property_tree::ptree pt; 
    read_xml(filename, pt); 
    readConfig(pt, entry);  // <= Calling pure virtual function! 
} 

基本上字符串版本僅僅是一個快速的包裝純粹的虛擬形式。當我編譯此,我得到一個錯誤:

no known conversion for argument 1 from std::string to boost::property_tree::ptree` 

如此看來,在非虛函數(從Base)沒有被識別爲可利用。我檢查了我的派生類的定義是確定的:

class Deriv : public Base 
{ 
    // ... 
    void readConfig(boost::property_tree::ptree, string); // implement virtual, error is on this line 
} 

void Deriv::readConfig(boost::property_tree::ptree pt, string entry) 
{ 
    //... 
} 

注意,我省略const -correctnes很多,通過參考等傳遞使代碼更易讀一點。

我能做些什麼來解決這個問題?在非虛函數中使用純虛成員函數是一個好主意?

+0

'Deriv.h',我聲明函數的那一行。 – romeovs

+0

你實際上不會在正確編寫的程序中調用純粹的病毒函數。相反,你會調用相應的派生率最高的覆蓋,其中至少有一個覆蓋。 –

+0

你的程序是否真的崩潰,說「純虛函數調用」? –

回答

3

見FAQ中的項目 「什麼的,警告的含義:衍生:: F(char)的隱藏基地:: F(雙)」可在許多常見問題的鏡像中獲得,包括原始的English version of the FAQ

在發佈前檢查常見問題解答通常是一個好主意。

很有可能您也會發現有用的(雖然不是針對直接問題)標題爲「好的,但是有沒有一種方法來模擬該行爲,好像動態綁定對我的基礎中的該對象起作用類的構造函數?「,再加上如果這變得相關,那麼你可能也有興趣閱讀my blog article about the DBDI problem

+0

哇,就是這樣..又浪費了一個下午!奇怪的是,他們沒有在課堂上講授......非常感謝! – romeovs

+0

我覺得這是繼承問題中最棘手的問題之一。避免它的一種方法是隻從'private'基礎繼承,並通過'using'聲明'public'接口中想要的成員(這又允許僅用一個聲明聲明重載成員)。 – Walter

2

明顯的錯字是顯而易見的:

virtual void readConfug 

,而不是

virtual void readConfig 

此外,你實現什麼叫做模板方法模式,僅供參考。

+0

哎呀,這是一個錯誤將它放在stackoverflow上。是的,我知道這將是一種設計模式! – romeovs

+0

@romeovs我沒有看到任何其他代碼問題。你能否重現一個表達問題的最小例子 - 這個編譯。 –

+0

我很懷疑..這個問題必須更深入,可能是一些指針搞砸了。我想說明一下,但問題是'Base'和'Deriv'之間存在另一個純虛擬類。我會看看我能做什麼。 – romeovs