如何在读取和写入时禁用std :: iostream try catch

时间:2016-11-13 15:46:56

标签: c++ exception iostream

#undef _HAS_EXCEPTIONS
#define _HAS_EXCEPTIONS 0

#include <stdio.h>
#include <streambuf>
#include <ostream>
#include <iostream>
#include <fstream>

using namespace std;


class MyIoStream : public std::basic_iostream< char, std::char_traits< char > >
{
public:
    class MyBuffer : public std::basic_streambuf<char, std::char_traits<char> >
    {

    public:
        streamsize __CLR_OR_THIS_CALL xsputn(const char *_Ptr,
            streamsize _Count)
        {
            par->clear();
            par->setstate(ios_base::goodbit);
            printf("write\n");
            return _Count;
        }
        streamsize __CLR_OR_THIS_CALL _Xsgetn_s(char * _Ptr,
            size_t _Ptr_size, streamsize _Count)
        {
            par->clear();
            par->setstate(ios_base::goodbit);
            a = a + 1;
            if(a == 2)
                throw "asdf";
            printf("read\n");
            return _Count;
        }
        MyIoStream* par;
        int a;
    };
public:

    MyIoStream() :
    std::basic_iostream< char, std::char_traits< char > >(&buf)
    {
        buf.par = this;
        buf.a = 0;
    }

private:

    MyBuffer buf;

};

void MyRead(istream* pIs, int siz, void* buf)
{
    try
    {
        pIs->read((char*)buf, siz);
    }
    catch(char*)
    {
        printf("my catch\n");
    }
}

void MyWrite(ostream* pOs, int siz, void* buf)
{
    pOs->write((const char*)buf, siz);
}

int main(void)
{
    MyIoStream o;
    char buf[1234];

    MyRead((istream*)&o, 10, buf);
    MyWrite((ostream*)&o, 10, buf);
    MyWrite((ostream*)&o, 10, buf);
    MyRead((istream*)&o, 10, buf);
    MyRead((istream*)&o, 10, buf);
    MyWrite((ostream*)&o, 10, buf);
    MyRead((istream*)&o, 10, buf);
    MyRead((istream*)&o, 10, buf);

    return 0;
}

我正在尝试从std :: iostream继承一个类MyIoStream。 覆盖的函数MyBuffer :: xsputn和MyBuffer :: _ Xsgetn_s抛出异常,我需要抓住自己,但抛出的异常会被基类捕获。

1 个答案:

答案 0 :(得分:0)

假设您想要捕获MyBuffer :: xsputn内部或MyBuffer :: _ Xsgetn_s内部的异常,您可以将方法中的代码包装在try-catch块中。

在我自己的自定义LogFile类中,我从std :: streambuf继承,并使用cout.rdbuff(...)重定向ostream所在的位置。但是,在完成类之后,必须将指针返回到默认的streambuff。我已经在下面列出了一个精简版本:

class Logger : public std::streambuf
{
public:
    std::streamsize xsputn (const char* s, std::streamsize n) 
    {
        /* Your Code Here */
    }

    template <typename T>
    friend Logger& operator<<(Logger& logger, const T& v);

    Logger()
    {
        m_pPrevStreamBuffer = cout.rdbuf(this);
    }

    virtual ~Logger();
    {
        cout.rdbuf(m_pPrevStreamBuffer);
    }

private:
    std::streambuf* m_pPrevStreamBuffer;
    String m_CurrentLine;
};