Ben*_*Ben 5 c++ pointers smart-pointers stream c++11
我正在制作一个简单的日志类,其中包含指向 astd::ofstream或std::cerr.
无论使用哪个流,是否有任何简单的方法可以使用智能指针进行自动清理?
代码必须在 clang++、g++ 和 VS2013 上编译。
#include <iostream>
#include <fstream>
#include <string>
class Logger {
private:
std::ostream * output_stream{ nullptr };
bool using_file{ false };
public:
Logger()
{
output_stream = &std::cerr;
using_file = false;
}
Logger(std::string file)
{
output_stream = new std::ofstream(file);
using_file = true;
}
~Logger()
{
if (using_file)
{
delete output_stream;
}
}
template<typename T>
void log(T info)
{
*output_stream << info << std::endl;
}
};
class tmp {
int i{ 4 };
friend std::ostream & operator<<(std::ostream &os, const tmp& p);
};
std::ostream &operator<<(std::ostream &os, const tmp& p)
{
return os << p.i;
}
int main()
{
tmp t;
Logger logger;
logger.log(t);
system("pause");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
std::unique_ptr我可以std::unique_ptr像这样用于文件:
std::unique_ptr<std::ostream> p;
p = std::make_unique<std::ofstream>("file.txt");
*p << "hi there" << std::endl;
Run Code Online (Sandbox Code Playgroud)
尝试此操作会std::cout警告我已删除的函数(假设这是构造函数。
std::unique_ptr<std::ostream> p2;
p2 = std::make_unique<std::ostream>(std::cout);
*p2 << "hey" << std::endl;
Run Code Online (Sandbox Code Playgroud)
std::shared_ptr因为std::unique_ptr只是为了拥有东西,std::cout不应该拥有,我想我会尝试std::shared_ptr
std::shared_ptr<std::ostream> p;
p = std::make_shared<std::ostream>(std::cout);
*p << "hola" << std::endl;
Run Code Online (Sandbox Code Playgroud)
它给了我相同的删除构造函数错误。p = &std::cout抱怨类型不匹配,所以它也不起作用。
您可以将 ashared_ptr与删除器一起使用,该删除器在 的情况下不会删除任何内容,cerr而shared_ptr在ofstream
class Logger {
private:
std::shared_ptr<std::ostream> output_stream{ nullptr };
public:
Logger() :
output_stream(&std::cerr, [](std::ostream*){})
{ }
Logger(std::string file) :
output_stream(std::make_shared<std::ofstream>(file))
{ }
// default destructor is OK
template<typename T>
void log(T info)
{
*output_stream << info << std::endl;
}
};
Run Code Online (Sandbox Code Playgroud)
我只会有两个指针,一个聪明的,一个原始的。
原始指针始终用于引用流。如果需要,智能指针仅用于清理。
class Logger {
private:
std::unique_ptr<std::ofstream> file_stream;
std:ostream *stream;
public:
Logger() : stream(&std::cerr) {}
Logger(const std::string& file)
: file_stream(std::make_unique<std::ofstream>(file)), stream(file_stream.get()){}
template<typename T>
void log(T info) {
*stream << info << std::endl;
}
};
Run Code Online (Sandbox Code Playgroud)