2015-12-25 184 views
1

我有以下兩類:初始化成員變量一旦

class foo{ 
public: 
    foo(){ 
     Configuration config; 
     config.a=5; 
     config.b=5; 
     //... 
     config.z=5; 
     eng=Engine(config); 
    } 
private: 
    Engine eng; 
} 

class Engine{ 
public: 
    Engine(){ 
     //Very have model loading from hard disk is occurs here 
     //This loading is depend on the values of config 
    }; 
    Engine(Configuration const& config):config(config){ 
     //Very have model loading from hard disk is occurs here 
     //This loading is depend on the values of config 
    } 
private: 
    Configuration config; 
} 

很明顯在foo初始化eng成員變量的方式constructor是非常糟糕的監守eng已被初始化兩次(這是非常昂貴)。爲了解決這個問題,我做了engunique_ptr和使用std::make_uniquefoo constructor在初始化一次:

class foo{ 
    public: 
     foo(){ 
      Configuration config; 
      config.a=5; 
      config.b=5; 
      //... 
      config.z=5; 
      eng=std::make_unique<Engine>(config); 
     } 
    private: 
     std::unique_ptr<Engine> eng; 
    } 

這解決了不必要的初始化的問題。但是,我認爲我已經以錯誤的方式解決了這個問題。我看不出明顯的理由使用pointers。我認爲stack member variables有更好的解決方案。

問題是:是否應該儘量避免使用基於指針的解決方案?如果是的話,我的情況最好的解決方案是什麼?

編輯:

有人可能認爲簡單的解決辦法,我應該爲在engineconfig一個setter方法。所以,我可以在加載後進行設置。這不是一個選項,因爲加載過程取決於config。所以如果我改變config我應該再次加載

+0

也許'引擎(配置配置):配置(配置){'應該'引擎(常量配置和配置):配置(配置){性能 –

+0

是的確定它是這樣的..我只寫這個代碼所以。謝謝 –

+1

也許發佈你實際使用的代碼是更好的選擇,以獲得更多信息的答案 –

回答

5

Configuration準備就移動到一個成員函數:

class foo{ 
public: 
    foo() : eng(prepare_config()){ 
    } 

    Configuration prepare_config() { 
     Configuration config; 
     config.a=5; 
     config.b=5; 
     //... 
     config.z=5; 
     return config; 
    } 
private: 
    Engine eng; 
} 

確保不訪問任何foo成員prepare_config()(或只是讓prepare_config()靜態)。

+0

這種解決方案,我一直在尋找..很多謝謝..順便說一句,你認爲這種解決方案是絕對比使用指針? –

+1

@HumamHelfawi,我不喜歡說某件事情比其他任何事情都好。每種解決方案都有其優點和缺點;這一切都取決於你的情況的更精細的細節。例如,如果您實際上需要一些'foo'成員來準備'Configuration',那麼這個代碼可能會更困難並且容易出錯。 – Petr