c++ - 难以为文件处理类重载运算符<<

标签 c++ oop iostream raii

我必须:

Define a File_handle class with constructor that takes a string argument (file name), opens the file in the constructor, and closes it in the destructor.

据我了解,此类用于提供 RAII,我正在尝试使用 FILE* 实现该类作为基本数据结构,我的目标基本上是制作 FILE*一个智能指针:

fileHandler.h :

// Class CFile_handler based on FILE*
class CFile_handler {
public:
    CFile_handler();                                           // default constructor   
    CFile_handler(const std::string& fileName,                 // constructor
                  const std::string& mode);     
    ~CFile_handler ();                                          // destructor

    // modifying member function
    void open_file(const std::string& fileName, 
                   const std::string& mode);

protected:
    typedef FILE* ptr;

private:
    CFile_handler(const CFile_handler&);                        // prevent copy creation
    CFile_handler& operator= (const CFile_handler&);            // prevent copy assignment

    ptr c_style_stream;                                         // data member
};

fileHandler.cpp :

// Class CFile_handler member implementations
// default constuctor
CFile_handler::CFile_handler() {

}

// constructor
CFile_handler::CFile_handler(const std::string& fileName, const std::string& mode = "r")
    : c_style_stream( fopen( fileName.c_str(), mode.c_str() ) ) 
{

}

// destructor
CFile_handler::~CFile_handler() {
    if (c_style_stream) fclose(c_style_stream);
}

// Modifying member functions
void CFile_handler::open_file(const std::string& fileName, const std::string& mode) {
    c_style_stream = ( fopen( fileName.c_str(), mode.c_str() ) );
}

但是,我在重载 I/O 时遇到困难 operators<</>> ,因为我不知道如何实现它们中的任何一个。

如何重载operator<<这样该类就可以与 iostream 对象一起工作?

编辑:

正如@LokiAstari 提出的那样,从istream 继承会是更好的策略。并定义自己的 streambuf .

有人可以给出实现 streambuf 的示例或说明吗?处理 FILE*


我要提供的是:

CFile_handler fh("filename.txt", "r");

std::string file_text;
fh >> file_text;

或:

CFile_handler fh("filename.txt", "w");

fh << "write this to file";

最佳答案

您可以使用 std::streambuf 派生 std::streams 的类型来处理 FILE*

#include <iostream>
#include <stdio.h>

class OutputFilePointerStream: public std::ostream
{
    class OutputFilePointerStreamBuf: public std::streambuf
    {
        FILE*   buffer;
        public:
            OutputFilePointerStreamBuf(std::string const& fileName)
            {
                buffer  = fopen(fileName.c_str(), "w");
            }
            ~OutputFilePointerStreamBuf()
            {
                fclose(buffer);
            }
            virtual std::streamsize xsputn(const char* s, std::streamsize n) override
            {
                static char format[30];
                sprintf(format, "%%.%lds", n);
                fprintf(buffer, format, s);
                return n;
            }
    };
    OutputFilePointerStreamBuf       buffer;
    public:
        OutputFilePointerStream(std::string const& fileName)
            : std::ostream(nullptr)
            , buffer(fileName)
        {
            rdbuf(&buffer);
        }
};

int main()
{
    OutputFilePointerStream      fileStream("Test");

    fileStream << "Testing: " << 5 << "><\n";
    fileStream << "Line Again\n";
}

关于c++ - 难以为文件处理类重载运算符<<,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35240857/

相关文章:

c++ - 如何在Qt Creator中制作.exe文件

php - 有没有办法在php中实现多重继承?

C++ char 单引号与双引号和内存内部工作原理

c++ - 替代控制台输出流

c++ - 为什么使用 'new' 是个坏主意?

c++ - 在运行时旋转俄罗斯方 block

python - 我什么时候应该使用 setUpClass 什么时候使用 __init__?

class - 如何从具有相同名称 IsTesting() 的类方法调用内置函数 IsTesting()?

c++ - 新编译器 - 使用 Cout?

c++ - 为什么 vector<std::function> 的元素可以绑定(bind)到 C++ 中的不同函数签名?