OutputStream打印'1',出于某种原因

时间:2014-02-22 18:07:08

标签: c++ operator-overloading ostream

出于某种原因,当我尝试将std :: endl与我的OutputStream对象一起使用时,它会在屏幕上和文件中打印“1”! (我认为它实际上是试图打印OutputStream对象本身,但我可能是错的。)这是我的代码:

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; },但没有解决问题......

3 个答案:

答案 0 :(得分:1)

我相信你需要为这样的函数指针(操纵器)创建一个重载:

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

    return *this;
}

答案 1 :(得分:0)

我试图将函数指针(endl)传递给operator&lt;&lt;。也就是说,我试图“打印”一个函数指针(一个地址)。它起作用,因为我已经定义了这个功能来完成它的工作。

答案 2 :(得分:0)

尝试重载operator<<以接受指向方法的指针作为参数。

第二个选项是在OutputStream中创建一个名为(例如)endl的新类(类似于定义类特定异常的方式),如下所示:

class endl{}

之后,您需要做的就是使运算符&lt;&lt;支持这种类:

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

并像这样使用它:

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