[英]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
相同的功能。
相關:
我希望使用 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.