簡體   English   中英

ofstream 的默認“NULL”值

[英]Default “NULL” value for an 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 類參數中接受的答案建議不帶ofs參數的重載。 在我的情況下,這可能不起作用,因為我的意思是在“ ofs=NULL ”時不寫任何內容。

注 4另一個答案顯然有效,但對我來說似乎有些人為,我不確定它是否提供與傳遞ofs相同的功能。

相關

C++ 或庫中是否有空 std::ostream 實現?

我希望使用 myfun 的應用程序仍然可以在不進行任何修改的情況下工作。

如果是這樣,請使用默認為nullptr的 ofs

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

    // ...
}

您不能對此類函數使用ofstream& ofs引用參數,因為引用不能為空。

制作一個抽象的 Logger 類。 它有一個記錄消息的方法。 在派生類中,您可以將日志記錄添加到文件 (ofstream) 中,或者干脆什么都不做。 您可以使用任何記錄器,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
}

這種解決方案的缺點雖然是慣用的,但在某些情況下是冗長和沉重的語法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM