微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ofstream

如何解决ofstream

我目前有一个功能

int myfun(const int a) {
    ...
    return rval;
}

执行多项操作。

我的意思是根据我可以传递的某些参数,对其进行修改,以编写有关其行为的调试信息或不进行调试。 在我要编写该信息的情况下,我也想传递ofstream来使用。 而且我希望使用myfun的应用程序仍然能够不做任何修改

所以我理想上将更改为

int myfun(const int a,ofstream & ofs) {
    ...
    if (!(ofs == NULL)) {
        ofs << ...
    }
    ...
    if (!(ofs == NULL)) {
        ofs << ...
    }
    return rval;
}

,其认值类似于&ofs=NULL。我知道NULL不适合。

什么是合适的处理方式?

注释1 : 我可以在输出文件名中传递一个可选参数,但这不太灵活。

注释2 : 我也可以更改为

int myfun(const int a,const bool debug_info,ofstream & ofs) {
    ...
    if (debug_info) {
        ofs << ...
    }

,其认值为debug_info=false。 我想这仍然需要ofs认值,如上所述。

注释3 Default ofstream class argument in function中接受的答案提出了没有ofs参数的重载。 就我而言,这可能行不通,因为我的意思是在“ ofs=NULL”时不写任何内容

注释4 This other answer显然有效,但对我来说似乎有些伪造,而且我不确定它是否提供与传递ofs相同的功能

相关

Is there a null std::ostream implementation in C++ or libraries?

解决方法

我希望使用myfun的应用程序仍然可以正常运行,而无需进行任何修改。

如果是这样,请使用默认值为nullptr的ofs

int myfun(const int a,ofstream *ofs = nullptr)
{
    if (ofs != nullptr)
    {
        // (*ofs) << ... ;
    }

    // ...
}

您不能将引用参数ofstream& ofs用于此类功能,因为引用不能为空。

,

制作一个抽象的Logger类。它具有一种记录消息的方法。在派生类中,您可以将日志记录添加到文件(流)中,或者什么都不做。您可以使用任何记录器,myfun()的实现保持不变。

#include <fstream>

class Logger {
public:
    virtual void log(const char*) = 0;
};

class NullLogger: public Logger {
public:
    void log(const char*) override {};
};

class FileLogger: public Logger {
public:
    FileLogger(std::ofstream& s): ofs(s){}
    void log(const char* msg) override {
        ofs << msg;
    }
private:
    std::ofstream& ofs;
};

static NullLogger defaultLogger;
int myfun(const int a,Logger& logger=defaultLogger)
{
    logger.log("hello");
    // ...
    logger.log("asdf");
}

int main(){
    std::ofstream ofs;
    FileLogger fileLogger(ofs);
    NullLogger nullLogger;
    myfun(10,fileLogger); // logs to file
    myfun(10,nullLogger); // logs nothing
    myfun(10); // also logs nothing
    return 0;
}
,

在C ++ 17中,有一个涉及std::optional的解决方案,但是由于它需要默认的可构造类型,因此也必须使用std::reference_wrapper

#include <fstream>
#include <optional>
#include <functional>

int myfun(const int a,std::optional<std::reference_wrapper<std::ofstream>> ofs)
{
    if (ofs) {
        ofs->get() << "...";
        return 1;
    }
    else{
        return 0;
    }
}
#include <iostream>
int main(){
    std::ofstream file;
    //Calling is quite nice.
    std::cout<<myfun(10,{file})<<'\n'; //Prints 1
    std::cout<<myfun(10,{})<<'\n'; //Prints 0
}

该解决方案的缺点虽然很惯用,但在某些情况下却过于冗长且语法繁重。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。