2014-02-22 54 views
0

出於某種原因,當我嘗試使用std :: ENDL我的OutputStream對象,它打印「1」都在屏幕上,並在文件中! (我認爲它實際上是要打印的OutputStream對象本身,但我可能是錯的。)下面是我的代碼:的OutputStream打印「1」,出於某種原因,

OutputStream.h

#ifndef OUTPUTSTREAM_H 
#define OUTPUTSTREAM_H 

#include <fstream> 
#include <iostream> 
#include <string> 

class OutputStream : public std::ostream 
{ 
    public: 
     OutputStream(const std::string&); 
     virtual ~OutputStream(); 
     //template <typename T> OutputStream& operator<<(T); 
     template <typename T> OutputStream& operator<<(T& data) 
     { 
      std::cout << data; 
      *(this->file) << data; 
      return *this; 
     } 
     template <typename T> OutputStream& operator<<(const T& data) 
     { 
      std::cout << data; 
      *(this->file) << data; 
      return *this; 
     } 
     void changeDestinationTo(const std::string&); 
     std::string getDestination() const; 
     // overloading the endl operator to allow for the same functionality that exists on other ostream objects, and returning 
     // the same type allows for cascading calls 
     static OutputStream& endl(OutputStream&); 
    protected: 
    private: 
     std::string filename; 
     std::ofstream * file; 
}; 

#endif // OUTPUTSTREAM_H 

OutputStream.cpp

#include "OutputStream.h" 

#include <iostream> 
#include <fstream> 
#include <new> 
#include <string> 

OutputStream::OutputStream(const std::string& theFileName) 
{ 
    // specify the filename 
    this->filename = theFileName; 
    // open the fileName with that file 
    this->file = new(std::nothrow) std::ofstream(this->filename.c_str()); 
} 

OutputStream::~OutputStream() 
{ 
    // delete the file! (no, not really) 
    this->file->close(); 
    delete this->file; 
} 

/*template <typename T> 
OutputStream& OutputStream::operator<<(T) 
{ 
    std::cout << data; 
    *(this->file) << data; 
    return *this; 
} 

template <typename T> 
OutputStream& OutputStream::operator<<(T& data) 
{ 
    std::cout << data; 
    *(this->file) << data; 
    return *this; 
} 

// the const-correct version of the above function 
template <typename T> 
OutputStream& OutputStream::operator<<(const T& data) 
{ 
    // writing the data to std::cout 
    std::cout << data; 
    // writing the data to the file that we specify 
    *(this->file) << data; 
    return *this; 
} 
*/ 
void OutputStream::changeDestinationTo(const std::string& newFileName) 
{ 
    // close the currently-open file 
    this->file->close(); 
    // open up the file at newFileName 
    this->filename = newFileName; 
    this->file->open(newFileName.c_str()); 
} 

std::string OutputStream::getDestination() const { return this->filename; } 

OutputStream& OutputStream::endl(OutputStream& myStream) 
{ 
    // call std::endl on both std::cout and *(this->file) 
    std::cout << std::endl; 
    *(myStream.file) << std::endl; 
    // allow for cascading by returning myStream 
    return myStream; 
} 

main.cpp

#include "Array.h" 
#include "OutputStream.h" 

#include <iostream> 

using namespace std; 

int main() 
{ 
    // setup the OutputStream 
    OutputStream outputter("file.txt"); 
    // do some stuff with it 
    outputter << "This is a test to make sure that it works.\n"; 
    outputter << "25 + 3.7 == " << 25 + 3.7 << '\n'; // doesn't print '1' 
    outputter << "\nNow testing this with objects:\n" << OutputStream::endl; // prints '1' 
    // declare an Array of 10 ints 
    Array<int> someArray(10); 
    // output them 
    outputter << "Printing an Array:\n"; 
    outputter << someArray << OutputStream::endl; 
    return 0; 
} 

有沒有什麼方法可以很容易地解決這個問題? (我曾嘗試聲明friend std::ostream& operator<<(std::ostream& standardStream, const OutputStream& myOutputStream) { return standardStream; }但沒有采取任何行動來解決問題...

回答

1

我相信你需要創建函數指針(機械手),像這樣的超載:

template<typename T> 
OutputStream& operator<<(std::ostream& (*manip)(std::ostream&)) 
{ 
    manip(*this->file); 
    manip(std::cout); 

    return *this; 
} 
+0

是的,這就是我最終做的,它的工作!我發現這裏的解決方案:http://stackoverflow.com/questions/1134388/stdendl-is-of-unknown-type-when-overloading-operator 儘管如此,我仍然會試圖理解爲什麼我的方式產生的結果是(我的原始方式仍然有效,但每次使用endl時都打印出'1')。我想我知道爲什麼,並且我會試着在這裏把它說出來。 //它可能需要一段時間 –

+0

@MikeWarren原因是因爲你正在打印一個函數指針,它選擇'ostream :: operator <<(ostream&,bool)',因此它被隱式轉換爲bool,因此輸出爲1. – 0x499602D2

+0

Holy廢話,我只是在看到這個之前得出這個結論(並且只是想着發生了什麼)! (也就是說,我想了一會,發佈了答案,當頁面刷新時,我看到了你的評論!!真是巧合!!)順便說一句,謝謝你的答案,我剛剛學到了一些東西! ! –

0

我試圖通過一個函數指針(endl)給運算符< <。也就是說,我試圖「打印」一個函數指針(一個地址),它的工作原理是因爲我已經定義了該函數來完成它的工作

0

嘗試重載operator<<接受指向方法的指針作爲參數。

的第二個選擇是創建中的OutputStream ENDL(類似於做定義類特殊例外的方式)像這樣一個新的類名爲(例如):

class endl{} 

後,所有你需要做的是使運營商< <支持這種類型的類:

OutputStream& operator<<(OutputStream::endl& endl){ 
    cout << endl; 
    *flie << endl; 
    return *this; 
    } 

,並使用它像這樣:

outputer << "some string" << endl();