Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 重载运算符的困难<&书信电报;用于文件处理类_C++_Oop_Iostream_Raii - Fatal编程技术网

C++ 重载运算符的困难<&书信电报;用于文件处理类

C++ 重载运算符的困难<&书信电报;用于文件处理类,c++,oop,iostream,raii,C++,Oop,Iostream,Raii,我必须: 使用构造函数定义一个File\u handle类,该构造函数接受一个字符串参数(文件名),在构造函数中打开文件,然后在析构函数中关闭文件 据我所知,该类用于提供RAII,我正在尝试使用FILE*作为基本数据结构来实现该类,其中我的目标基本上是使FILE*成为智能指针: fileHandler.h: // Class CFile_handler based on FILE* class CFile_handler { public: CFile_handler();

我必须:

使用构造函数定义一个
File\u handle
类,该构造函数接受一个字符串参数(文件名),在构造函数中打开文件,然后在析构函数中关闭文件

据我所知,该类用于提供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
};
// 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() ) );
}
fileHandler.cpp

// 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
};
// 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
操作符方面遇到了困难,因为我不知道如何实现这两个操作符


如何重载
操作符您的
操作符您可以使用std::streambuf派生std::streams的类型来处理文件*

#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";
}
#包括
#包括
类OutputFilePointerStream:public std::ostream
{
类OutputFilePointerStreamBuf:public std::streambuf
{
文件*缓冲区;
公众:
OutputFilePointerStreamBuf(标准::字符串常量和文件名)
{
buffer=fopen(fileName.c_str(),“w”);
}
~OutputFilePointerStreamBuf()
{
fclose(缓冲区);
}
虚拟std::streamsize xsputn(常量字符*s,std::streamsize n)重写
{
静态字符格式[30];
sprintf(格式,“%.%lds”,n);
fprintf(缓冲区、格式、s);
返回n;
}
};
OutputFilePointerStreamBF缓冲区;
公众:
OutputFilePointerStream(标准::字符串常量和文件名)
:std::ostream(nullptr)
,缓冲区(文件名)
{
rdbuf(缓冲区和缓冲区);
}
};
int main()
{
OutputFilePointerStream文件流(“测试”);

fileStream您需要更具体地说明您正在尝试执行的操作。您是否正在尝试使用@Puppy将内容放入CFile_处理程序?是的,我正在尝试实现上述两个操作。我只包含了
运算符的声明为什么是否决票和结束票?您可以添加注释吗?@simplicisveritatis嗯,通常您不会继承标准库中的类,但只使用它们。我仍然不清楚您想要实现什么,尤其是使用
CFile\u处理程序
类。只有在构建时需要从类外部传递这些类时,包装
文件*
才有意义。如果您希望它与所有现有流功能一起工作,则(并且不要编写自己的运算符或感谢您的时间和帮助。我编辑了这个问题,以澄清我想要实现的功能。您能否就实现的方向给出一些说明,即使用什么函数来写入数据成员
ptr
?@simplicisveritatis假设
ptr
文件*
,然后在显示的示例中,只需在函数中执行,例如,
fprintf(c_-style_-stream,“%d”,value);
。@simplicisveritatis对于读取,只需执行相反的操作(例如,
operator>
,通过引用获取
参数,以便可以对其进行更改,请使用
fscanf
)一个C++流类只不过是一个简单的类,有很多代码>操作符< /代码>和代码操作符> <代码>过载。你的代码> cFielyHuffer-<代码>是一个流,如果我理解你的任务,那么你的类应该是“流”。。很抱歉误解,因此我必须为所有内置类型(
int
char
double
,等等)编写
operator>,
fscanf()
)作为C函数(
fprintf()
fscanf()
)的包装,并使用相应的格式设置(
%d
)等),对吗?它工作得很好!我想
xsputn
涉及到内部缓冲机制,这可能与写入输出有关,这在逻辑上意味着我必须编写类似
xgetn
的内容来读取
“r”的输入
mode。无论如何,感谢您提供的有用示例!@simplicisveritatis:请参阅查看虚拟受保护成员函数
CFile_handler& operator<<(CFile_handler& file, int value)
{
    // Output an integer to the file contained in `file`
    return file;
}
CFile_handler my_file(...);
my_file << 1234;
#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";
}