2014-03-24 48 views
1

我正在爲我的架構類寫一個分支預測模擬器,並且在多個類之間獲得輸出工作時遇到了一些麻煩。我試圖在main.cpp中打開一個mainstream,並將其傳遞給每個類的構造函數以供對象使用。我收到了一大堆的錯誤在我的頭文件,如:錯誤當試圖傳遞一個對象到一個對象(C++)

In file included from main.cpp:4:0: 
predictors.h: In constructor â?~ATPred::ATPred(std::ofstream&)â?T: 
predictors.h:14:18: error: use of deleted function â?~std::basic_ofstream<char>& std::basic_ofstream<char>::operator=(
const std::basic_ofstream<char>&)â?T 

因此,錯誤似乎是在我的頭文件:

#ifndef PREDICTORS_H 
#define PREDICTORS_H 

#include <string> 

// Always Taken 
class ATPred{ 
    private: 
      std::ofstream outputFile; 

    public: 
      // Constructor 
      ATPred(std::ofstream& file) 
      { outputFile = file; } 

      // Deconstructor 
      ~ATPred() 
      {} 

      // Member Functions 
      void parseResults(std::string filename); 
}; 

// Always Non-Taken 
class ANTPred{ 
    private: 
      std::ofstream outputFile; 

    public: 
      // Constructor 
      ANTPred(std::ofstream& file) 
      { outputFile = file; } 

      // Deconstructor 
      ~ANTPred() 
      {} 

      // Member Functions 
      void parseResults(std::string filename); 
}; 

#endif 

我不知道在哪裏,我在這裏出錯,所以任何幫助將不勝感激。

回答

0

這裏的問題是,你存儲的是ofstream的值而不是引用。您可以通過改變ANTPred(以及類似改變ATPred)代碼工作如下:

class ANTPred { 
private: 
    std::ofstream &outputFile; 
public: 
    ANTPred(std::ofstream &file) : outputFile(file) { 
     // other construction work 
    } 
}; 

雖然我說,這將使得你的代碼的工作,它不一定是安全。存儲對ofstream對象的引用隱含地假定它將超過所有ATPredANTPred實例。如果ostream首先被破壞,那麼ATPredANTPred實例的行爲將不確定,並可能導致段錯誤。其他選項的非詳盡列表包括使用原始指針(導致上面指出的相同的生命期問題),共享指針(C++ 11 std::shared_ptrboost::shared_ptr或某個其他共享指針庫),構建單獨的輸出爲每個對象創建流,或者當需要記錄數據時將輸出流傳遞給對象實例。

+0

我不會在主函數中關閉ofstream,直到完成所有通過對象的操作,仍然是不安全的? – Riptyde4

+0

這只是有風險的,因爲編譯器沒有編譯時可強制執行的合約。在我看來,如果這是應用程序的設計並且每個人都知道正在處理代碼的情況,那就沒問題。 – Nathan

+0

gotcha,謝謝!我是目前唯一處理代碼的人,所以我認爲這種模式沒有問題。 – Riptyde4

0

標準C++流不可複製,並且您按值存儲成員outputFile。您必須將其更改爲參考或指針。

0

流對象不能被簡單地複製和分配,因爲它不能被doesn't make sense to copy a stream

只要你的班級在附近(但要小心誰擁有這個對象),你可以存儲一個引用(或[智能]指針)到流中並確保該對象不會超出範圍。

無論如何,如果你有決心,this article提供的方法可以複製流,但是......

總的來說,創建一個流的副本是不平凡的,如果你真的需要應該只 做流對象的副本。在很多情況下,使用引用或指針來流式傳輸對象 更合適,或者在兩個流之間共享流緩衝區。

+1

我不認爲他打算實際上*複製*流。 – 0x499602D2

+0

是的,你是對的。這將僅供將來參考。 – manlio

0

首先 - 當構造函數的主體運行時,所有成員都應該被初始化。你只能分配給他們然後。要初始化的成員,你需要使用成員初始化列表:

struct X { 
     int i; 
     X() : i(42) // <-- member initiliazer 
     { } 
    }; 

二 - 流無法複製或分配。

您的選項是

  • 已引用或指針到流作爲成員
  • 已在類初始化流本身(你會構造函數將接受參數的流需求的構造,而不是另一個流)
+0

使用路徑名初始化它也可以。 – 0x499602D2