这是我的第一篇文章。
我阅读了很多主题,似乎我做得很好,但是当我尝试编译以下代码时,我再次遇到上述错误:
// Header file
#include <fstream>
#include <ostream>
#include <string>
using namespace std;
class CLogger
{
private:
ostream m_oStream;
public:
CLogger(ostream& oStream);
CLogger(const string sFileName);
};
// Implementation file
CLogger::CLogger(ostream& oStream) :
m_oStream(oStream) // <-- Here is the problem?!
{
}
CLogger::CLogger(const string sFileName) :
m_oStream(ofstream(sFileName.c_str()))
{
}
你能帮帮我吗?
非常感谢!
答案 0 :(得分:6)
CLogger::CLogger(ostream& oStream) : // <-- Here is the problem?!
m_oStream(oStream)
问题不在第一行,而是在第二行。
由于成员m_oStream
被声明为非引用,因此上面的第二行尝试复制oStream
这是不可能的,因为std::ostream
的复制构造函数被禁用通过使其成为private
,这是您在错误消息中看到的“无法访问私有成员。”
解决方法是:
std::ostream * m_oStream; //declare it as pointer.
bool m_deleteStream; //flag whether to delete m_oStream or not
现在这样做:
CLogger::CLogger(ostream& oStream) :
m_oStream(&oStream), m_deleteStream(false)
{
}
CLogger::CLogger(const string sFileName) :
m_oStream(new std::ofstream(sFileName)), m_deleteStream(true)
{
//Note : in C++03, you've to pass sFileName.c_str() to
//the constructor of std::ostream
}
然后你要把析构函数写成:
~CLogger()
{
if ( m_deleteStream )
{
delete m_oStream;
}
}
重要的一点是:由于这是一个资源管理(记录器)类,因此不可复制是一个好主意,因为复制对记录器实例没有意义。
答案 1 :(得分:0)
在
m_oStream(ofstream(sFileName.c_str()))
您构建ofstream
并使用它复制构建您的m_oStream
。只需写下
m_oStream(sFileName.c_str())
Streams既不是可复制的也不是可复制的,虽然它们是可移动的类型,所以我猜你的不在这个例子中使用C ++ 11。
出于同样的原因,
CLogger::CLogger(ostream& oStream) :
m_oStream(oStream)
无法运作。你不能制作副本,你只能移动(在C ++ 11中)或持有某种形式的引用。
旁注:
从您的示例中,您是否这样做并不完全清楚,但不要忘记在头文件中包含警戒。