2013-10-16 187 views
1

我已經閱讀了關於該主題的多個問題和答案,但不幸的是他們都沒有幫助。我想使用相同的調試文件輸出中的兩個類A和B,其中A的一個實例創建B的一個實例我有類似:C++:在初始化列表中初始化對ofstream的引用

class A { 
public: 
    A() : debug("debug.txt") { }; 
private: 
    std::ofstream debug; 
} 

class B { 
public: 
    B(std::ofstream &ofs) : debug(ofs) { }; 
private: 
    std::ofstream &debug; 
} 

B *b = new B(debugUnderlying); 
創建它的一個實例

它工作得很好。但是,我現在想要有一個額外的構造函數,可以在不使用流的情況下使用它。對象然後將打開一個新文件。我明白了,因爲我有一個參考,我需要在初始化列表中初始化它。我試過許多東西:

B() : debug() { debug.open("debug2.txt"); }; 

error: invalid initialization of non-const reference of type ‘std::ofstream& {aka std::basic_ofstream<char>&}’ from an rvalue of type ‘const char*’ 

B() : debug("debug2.txt") { }; 

error: value-initialization of reference type ‘std::ofstream& {aka std::basic_ofstream<char>&}’ 

或(很清楚,因爲我有一個臨時對象)

error: invalid initialization of non-const reference of type ‘std::ofstream& {aka std::basic_ofstream<char>&}’ from an rvalue of type ‘std::ofstream {aka std::basic_ofstream<char>}’ 

我怎樣才能做到這一點?感謝您的任何建議!

+0

'B * b = new B(debugUnderlying);'停止Java編程 – Manu343726

+0

您可以指定您的意思嗎?正如您可能已經猜到的,這不是原始代碼。 – Gunnar

+1

您沒有任何理由動態分配'B'實例。 – Manu343726

回答

1

您可以存儲一個指針和標誌的所有權:

class B { 
    public: 
    B() : stream(new ...), owner(true) {} 
    B(std::ostream& s) : stream(&s), owner(false) {} 
    ~B() { if(owner) delete stream; } 
    private: 
    std::ostream* stream; 
    bool owner; 
}; 

注意:我用ostream替換了stream。

+0

在我意識到必須用'* debug <<「在這裏」<< std :: endl;'在這裏「<< std :: endl;'這裏」<< std :: endl;''替換每個'debug <<「之後,謝謝! – Gunnar

0

解決您的錯誤:

B():debug(*(new std::ofstream("debug.txt"))){} 

但是:如果你這樣做,所以我想你會忘記刪除...

所以:

您更好地利用一個單獨的包裝調試對象

class Debug{ 
    std::ofstream debug; 
    //private ctor, you can't create an object for this class outside 
    Debug(const std::string& filename):debug(filename){} 
public: 
    //only way tou use this class is to call this method 
    static Debug* Instance(){ 
      //the one and only Debug object, created at first use: 
     static Debug theObj("debug.txt"); 
     return &theObj; 
    } 
    //write method 
    std::ostream& outstream(){ 
     return debug; 
    } 
}; 
//just for simplicity of use: 
#define dbgout Debug::Instance()->outstream() 

你也可以這樣定義宏:

#ifdef DEBUG 
    #define dbgout Debug::Instance()->outstream() 
#else 
    // a release version won't create the debug file... 
    #define dbgout // 
#endif  

現在你可以使用它像這樣在你的代碼的任何地方:

dbgout<<" put your " << "stream " <<" here "; 
+0

單例是一個dessign反模式。這只是一個令人敬畏的全局變量名稱。只要有可能就應該避免。 – Manu343726

+0

即使你使用單例,你也不應該返回一個指針,你應該返回一個引用。換句話說,不要讓用戶控制你的實例。如果用戶刪除實例會發生什麼? – Manu343726

+0

刪除將失敗,因爲它不是動態分配的。這樣的解決方案會讓他的生活變得輕鬆,那麼爲什麼不使用它呢? – SHR