C++ C++;:初始化对初始化列表中的流的引用
我已经阅读了关于这个话题的多个问题和答案,但不幸的是,这些问题和答案都没有帮助。我想在两个类A和B中使用相同的调试文件ouput,其中A的一个实例创建B的一个实例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:
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;
};