c++ 类构造函数“C2248:'std::basic_ios〈_Elem,_Traits>::basic_ios':无法访问class 'std::basic_ios〈_Elem,_Traits>中声明的私有成员”

ijxebb2r  于 2023-03-25  发布在  iOS
关注(0)|答案(2)|浏览(237)

这是我的第一个帖子。
我读了很多主题,看起来我做得很好,但是当我试图编译下面的代码时,我又得到了上面的错误:

// 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()))
{   
}

你能帮帮我吗?
非常感谢!

oymdgrw7

oymdgrw71#

CLogger::CLogger(ostream& oStream) : // <-- Here is the problem?!
m_oStream(oStream)

问题不在第一行,而是在第二行。
由于成员m_oStream被声明为非引用,上面的第二行试图复制oStream,这是不可能的,因为std::ostream的复制构造函数被禁用,因为它已经使private,这就是你在错误消息 “cannot access private member " 中看到的。
解决方法是:

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;
    }
 }

重要的一点是:由于这是一个资源管理(logger)类,因此使其不可复制将是一个好主意,因为复制对于logger示例没有意义。

yeotifhr

yeotifhr2#

m_oStream(ofstream(sFileName.c_str()))

构造一个ofstream并用它复制构造m_oStream

m_oStream(sFileName.c_str())

流既不是可复制构造的,也不是可复制赋值的,尽管它们是可移动的类型,所以我猜你在这个例子中使用的不是C++11。
出于同样的原因,

CLogger::CLogger(ostream& oStream) : 
    m_oStream(oStream)

你不能复制,你只能移动(在C++11中)或持有某种形式的引用。
旁注:
从你的例子中还不完全清楚你是否这样做了,但是不要忘记在你的头文件中包含guards。

相关问题