2008-10-23 81 views
12

我想要一個純虛父類調用,像這樣一個孩子實現一個功能:C++父類調用子虛擬功能

class parent 
{ 
    public: 
    void Read() { //read stuff } 
    virtual void Process() = 0; 
    parent() 
    { 
     Read(); 
     Process(); 
    } 
} 
class child : public parent 
{ 
    public: 
    virtual void Process() { //process stuff } 
    child() : parent() { } 
} 

int main() 
{ 
    child c; 
} 

這應該工作,但我得到一個未鏈接錯誤:/這是使用VC++ 2k3

或者它不應該工作,我錯了嗎?

回答

2

一般會工作,但不適用於純虛擬基類的構造函數中的調用。在構建基類時,子類覆蓋不存在,因此您不能調用它。只要您在構建完整個對象後調用它,它就可以工作。

2

這是因爲你的調用是在構造函數中。在構造函數完成之前,派生類將無效,因此您的編譯器正在爲此定下決心。

有兩個解決方案:

  1. 執行調用以處理()在子類的構造函數
  2. 定義毛坯功能體用於過程如下面的例子:
class parent 
{ 
    public: 
    void Read() { //read stuff } 
    virtual void Process() { } 
    parent() 
    { 
     Read(); 
     Process(); 
    } 
} 
+0

這是危險的,定義一個空白父函數體並在其構造函數中調用它將導致只執行Process()的父部分(即無)。他可能希望將該調用作爲虛函數解析,這在構造函數中是不可能的 – Pieter 2008-10-24 08:25:51

+0

確實:將調用空函數。這不是可行的解決方案。 – xtofl 2008-10-24 09:32:49

4

或者,建立一個工廠方法來創建對象並使構造函數爲私有,工廠方法可以在構造之後初始化該對象。

0

你需要用在調用虛擬方法的對象中後,對象完全構造:

class parent 
{ 
    public: 
    void Read() { /*read stuff*/ } 
    virtual void Process() = 0; 
    parent() 
    { 
     Read(); 
    } 
}; 

class child: public parent 
{ 
    public: 
    virtual void Process() { /*process stuff*/ } 
    child() : parent() { } 
}; 

template<typename T> 
class Processor 
{ 
    public: 
     Processor() 
      :processorObj() // Pass on any args here 
     { 
      processorObj.Process(); 
     } 
    private: 
     T processorObj; 

}; 




int main() 
{ 
    Processor<child> c; 
} 
2

足下越多,你可能只是引入某種功能像

class parent 
{ 
    public: 
     void initialize() { 
      read(); 
      process(); 
     } 
} 
0

膚淺問題是你調用一個還不知道的虛擬函數(對象是由Parent to Child構造的,因此vtable也是如此)。你的編譯器警告過你。

必不可少的問題,據我所知,是你試圖通過繼承重用功能。這幾乎總是一個壞主意。設計問題,可以這麼說:)

本質上講,你嘗試實例化一個模板方法模式,從而分離出什麼:先讀一些數據(以某種方式),然後處理它(在某種方式)。

這可能會更好地處理聚合:將Processing函數賦予Template方法以在正確的時間調用。也許你甚至可以爲Read功能做同樣的事情。

聚集可以通過兩種方式來完成:

  1. 使用虛擬功能(即運行時綁定)
  2. 使用模板(即編譯時間綁定)

實施例1:運行時綁定

class Data {}; 
class IReader { public: virtual Data read()   = 0; }; 
class IProcessor { public: virtual void process(Data& d) = 0; }; 

class ReadNProcess { 
public: 
    ReadNProcess(IReader& reader, IProcessor processor){ 
     processor.process(reader.read()); 
    } 
}; 

實施例2:編譯時結合

template< typename Reader, typename Writer > // definitely could use concepts here :) 
class ReadNProcess { 
public: 
    ReadNProcess(Reader& r, Processor& p) { 
     p.process(r.read()); 
    } 
};