【问题标题】:trying to implement simple ostream singleton class试图实现简单的 ostream 单例类
【发布时间】:2015-06-14 12:40:45
【问题描述】:

我想实现一个接收文件路径作为参数的单例类。我尝试编写以下代码。我知道它不起作用而且不好,但我找不到原因..

class OutputData {
    std::fstream ofile;
    std::ostream iout;
    static OutputData *odata;
    OutputData(const char* path):iout(std::cout), ofile(path) {
        if (ofile.is_open()) {
            iout = ofile;
        }
    }
public:
    static void print(std::string s) {
        iout << s;
    }
};

在.cpp中

OutputData *OutputData::odata = nullptr;

从现在开始,我希望每个班级都能够写入该流。

谢谢

【问题讨论】:

  • 为什么要为此使用单例,而不仅仅是为OutputData 提供流operator&lt;&lt;() 重载??
  • 因为我的项目中有十几个类需要使用该流
  • 你没有明白我在说什么:将它作为参考传递而不是使用单例,其他一切都会不必要地使你的设计混乱(尤其是在大类层次结构中)。

标签: c++ singleton iostream


【解决方案1】:

您不能复制任何std::istreamstd::ostream 实例,您的成员变量应该是引用或指针:

class OutputData {
    std::fstream* ofile;
    std::ostream* iout;
    static OutputData *odata;
    OutputData(const char* path):iout(nullptr), ofile(nullptr) {
        ofile = new fstream(path);
        if (ofile->is_open()) {
            iout = ofile;
        }
        else {
            delete ofile;
            ofile = nullptr;
            iout = &cout;
        }
    }
    // Take care to provide an appropriate destructor
    ~OutputData() {
        delete ofile;
    }

};

关于你的单例设计,我更愿意推荐 Scott Meyer 的单例成语:

class OutputData {
public:
    static OutputData& instance(const char* path) {
        static OutputData theInstance(path)
        return theInstance;
    }
    // Make print a non-static member function
    void print(std::string s) {
        iout << s;
    }
};

虽然这种方法看起来很奇怪,但恰恰相反,因为它被认为是规范的解决方案。

【讨论】:

  • 我该如何启动它,比如说使用来自 main 的 argv?
  • @itorra 我严重怀疑,你真的想要一个单身人士。
  • 我为什么不呢?除了开始在整个项目中传递 OutputData 对象之外,还有什么经典解决方案?
  • @itorra " ... 开始在整个项目中传递 OutputData 对象?" 确实,这被认为是更好的解决方案。将其作为参数传递(可能通过接口)。不过,如果您确定要坚持使用Singleton,我在回答中给了您一个可行的解决方案。
  • 我明白了,并将与
猜你喜欢
  • 2011-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-20
  • 2011-07-12
相关资源
最近更新 更多