c++ - 如何使用智能指针进行自动清理?

标签 c++ pointers c++11 stream smart-pointers

我正在制作一个简单的日志记录类,它带有指向 std::ofstreamstd::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;
}

尝试

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;

尝试使用 std::cout 警告我有关已删除的函数(假设这是构造函数。

std::unique_ptr<std::ostream> p2;
p2 = std::make_unique<std::ostream>(std::cout);
*p2 << "hey" << std::endl;

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;

它给了我同样的 deleted constructor 错误。 p = &std::cout 提示类型不匹配,所以它也不起作用。

最佳答案

您可以将 shared_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;
    }
};

关于c++ - 如何使用智能指针进行自动清理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31750689/

相关文章:

c++ - Boost.Spirit.Qi - 规则开头的错误

c++ - 如何将指针传递给结构数组?

c++ - 在 C++ 中将 RGB 格式转换为 HDR 图像格式(EXR 格式)

c++ - C++中的非空终止字符数组

c++ - C++ 函数中的复杂参数 - 指针、引用或...?

c++ - 我的错误,还是英特尔编译器中的错误? sizeof 非静态成员错误

C++0x 内存模型和推测加载/存储

c++ - Qt 崩溃中工作线程的删除和清理

c++ - 假设在没有锁的线程中更改全局 bool 变量是崩溃安全的是否安全?

c++ - 使用 boost::variant 时运算符 * 不匹配