C++ C++;:初始化对初始化列表中的流的引用

C++ C++;:初始化对初始化列表中的流的引用,c++,pass-by-reference,ofstream,initializer-list,C++,Pass By Reference,Ofstream,Initializer List,我已经阅读了关于这个话题的多个问题和答案,但不幸的是,这些问题和答案都没有帮助。我想在两个类A和B中使用相同的调试文件ouput,其中A的一个实例创建B的一个实例 class A { public: A() : debug("debug.txt") { }; private: std::ofstream debug; } class B { public: B(std::ofstream &ofs) : debug(ofs) { }; private:

我已经阅读了关于这个话题的多个问题和答案,但不幸的是,这些问题和答案都没有帮助。我想在两个类A和B中使用相同的调试文件ouput,其中A的一个实例创建B的一个实例

class A {
public:
    A() : debug("debug.txt") { };
private:
    std::ofstream debug;
}

class B {
public:
    B(std::ofstream &ofs) : debug(ofs) { };
private:
    std::ofstream &debug;
}
并使用

B *b = new B(debugUnderlying);
这很有效。然而,我现在希望有一个额外的构造函数,能够使用它而不需要流。然后,对象将打开一个新文件。我明白了,因为我有一个引用,我需要在初始化列表中初始化它。我尝试了多种方法:

B() : debug() { debug.open("debug2.txt"); };

error: invalid initialization of non-const reference of type ‘std::ofstream& {aka std::basic_ofstream<char>&}’ from an rvalue of type ‘const char*’
B():debug(){debug.open(“debug2.txt”);};
错误:从“const char*”类型的右值初始化“std::of stream&{aka std::basic_of stream&}”类型的非常量引用无效

B():debug(“debug2.txt”){};
错误:引用类型“std::ofstream&{aka std::basic_of stream&}”的值初始化
或者(非常清楚,因为我有一个临时对象)

错误:从'std::ofstream{aka std::basic_of stream&}类型的右值初始化'std::ofstream&{aka std::basic_of stream&}类型的非常量引用无效

我该怎么做?谢谢你的建议

要修复错误:

B():debug(*(new std::ofstream("debug.txt"))){}
但是:如果你这样做,我想你会忘记删除

所以:

B():debug(*(new std::ofstream("debug.txt"))){}
最好使用单例来包装调试对象

class Debug{
    std::ofstream debug;
    //private ctor, you can't create an object for this class outside
    Debug(const std::string& filename):debug(filename){}
public:
    //only way tou use this class is to call this method
    static Debug* Instance(){
            //the one and only Debug object, created at first use: 
        static Debug theObj("debug.txt");
        return &theObj;
    }
    //write method
    std::ostream& outstream(){
        return debug;
    }
};
//just for simplicity of use:
#define dbgout Debug::Instance()->outstream()
您还可以这样定义宏:

#ifdef DEBUG
    #define dbgout Debug::Instance()->outstream()
#else
    // a release version won't create the debug file... 
    #define dbgout //
#endif    
现在,您可以在代码中的任何位置这样使用它:

dbgout<<" put your " << "stream " <<" here ";

dbgout您可以存储指针和标志所有权:

class B {
   public:
   B() : stream(new ...), owner(true) {}
   B(std::ostream& s) : stream(&s), owner(false) {}
   ~B() { if(owner) delete stream; }
   private:
   std::ostream* stream;
   bool owner;
};

注意:我用ostream替换了ofstream。

B*B=新的B(调试基础)停止Java中的编程您能指定您的意思吗?正如您可能猜到的,这不是原始代码。您没有任何理由动态分配
B
实例。从未意识到这一点。事实上,在那之前我就已经学过Java了。谢谢你的提示!(虽然动态分配不会有什么坏处,对吧?)singleton是一个design反模式。这是唯一一个全局变量的名字。应该尽可能避免它。即使使用单例,也不应该返回指针,而应该返回引用。换句话说,不要让用户控制你的实例。如果用户删除实例会发生什么情况?由于未动态分配实例,删除操作将失败。这样的解决方案会让他的生活变得轻松,为什么不使用它呢?用户不知道指针是否指向动态分配的内存块。他可以在代码中看到。如果你删除了一个指针,并且出现了分段错误,这意味着你做错了什么。在我意识到我必须替换每个
调试之后,这一切都很糟糕
class B {
   public:
   B() : stream(new ...), owner(true) {}
   B(std::ostream& s) : stream(&s), owner(false) {}
   ~B() { if(owner) delete stream; }
   private:
   std::ostream* stream;
   bool owner;
};