2013-03-29 61 views
0
class BaseClass { 
public: 
    BaseClass(const byte *buff, long size) { 
    // Some Computation 
    } 
}; 

class DerivedClass: public BaseClass { 
public: 
    std::vector<byte> filebuff; 
    long buff_size; 
    DerivedClass(): BaseClass(/*How should I send stuff here?*/) 
    { 
    } 
    /*return type??*/ cal_func(){ 
    // Some computation involving file descriptors. 
    // Store result in filebuff. Store size of filebuff in buff_size. 
    return /*what??*/; 
    } 
} 

我只能認爲以下溶液:C++:如何使用多個參數調用基類構造函數?

DerivedClass(): BaseClass(&filebuff[0], cal_func) 

在上述情況下,我將函數func()返回filebuff的長度。我依賴的事實是filebuff只是一個地址,因此編譯器首先將計算的func值放在堆棧上還是放在第一個arg filebuff上,這並不重要。

請告訴我這是否是正確的方法。如果第一個參數不是一個地址和一些其他需要在函數func中執行計算的計算值,那麼最好的方法是什麼?

+2

不,這是不正確的 - 在'filebuff'構造之前,你正在執行'&filebuff [0]'。 – ildjarn

+0

您能否介紹一下傳遞地址的最佳方法? –

+0

重新設計你的代碼 - 考慮使用組合而不是繼承。代碼中沒有任何內容表明對派生類的任何需求。 – ildjarn

回答

2

看起來好像你正在試圖包裝一個別人編寫的類(例如在一個不同的庫中),它有兩個參數,另一個類(你寫的)有一個更清晰的接口。我對麼?

您提出的解決方案是從其他基類派生,然後使用派生類來存儲放在基類中的參數。上述方法的問題在於,當您調用基類構造函數時,派生類尚未完全構造(即filebuff和bufsize無法保證被初始化爲任何內容)。

我建議另一種方法,在這裏,而不是派生,你有一個包含基類WrapperClass,以及你有兩個數據成員,就像這樣:

class Wrapper { 
public: 
    Base base; 
    std::vector<byte> filebuff; 
    long buff_size; 
    Wrapper(); 
} 

所以在構造函數包裝類,你可以做到以下幾點:

WrapperClass::WrapperClass() { 
    //do whatever you want to initialize filebuff and buffsize here 
    calcfunc(); 

    //now pass them in to your base class 
    base = Base(filebuff, buffsize); 
} 

[編輯]

替代

上述解決方案假定您的基類具有默認構造函數,即Base()。它可能不是,而且你不能創建一個。如果是這樣,那麼上面的代碼將不會編譯,因爲無法默認初始化base成員變量。另一種方法是使用指向基類的指針,例如Base*std::unique_ptr<Base>,或者直接使用一些此類機制而不是基本成員。這樣,您就可以準確控制Base類被初始化的時間。所以:

//class definition 
class Wrapper { 
public: 
    std::unique_ptr<Base> base; 
    std::vector<byte> filebuff; 
    long buff_size; 
    Wrapper(); 
} 

//... 

//constructor implementation 
WrapperClass::WrapperClass() { 
    //do whatever you want to initialize filebuff and buffsize here 
    calcfunc(); 

    //now pass them in to your base class 
    base = new Base(filebuff, buffsize); 
} 
+2

爲什麼'Base *'而不是'Base'?順便說一下,你的代碼違反了三條規則。 – ildjarn

+0

夠公平的。我只是試圖提供一個替代使用組合而不是繼承。我將編輯使用Base。 – maditya

+0

其實,我只是意識到,取決於基類是否具有爲初始化定義的默認構造函數... – maditya

2

的問題是,你要使用filebuff之前已經初始化,因爲基類的構造函數非靜態成員的構造函數之前調用。我同意ildjarn,最好的解決辦法是在這裏與成分來代替繼承:

class BaseClass { 
public: 
    BaseClass(const byte *buff, long size) { 
    // Some Computation 
    } 
}; 

class YourClass { 
public: 
    std::vector<byte> filebuff; 
    long buff_size; 
    BaseClass base; 

    DerivedClass() 
    : /* initialize filebuff and buff_size */, base(&filebuff[0], buff_size) {} 
}; 

成員將在它們出現在類定義的順序進行初始化,所以你就可以通過filebuffbuff_size到基地的構造。

另請參閱this answer以解決「C++:成員類的初始化順序」問題。

+1

我唯一真正想改變的就是完全丟失文件大小,並根據需要調整矢量大小,使用'base(filebuff)將其轉換爲基類。 data(),(long)filebuff.size())',但總的前提是好的,如果你可以在初始化列表中獲得正確大小的緩衝區。總而言之,一個好方法。 – WhozCraig

+0

@WhozCraig:謝謝。 – vitaut

相關問題