Search code examples
c++visual-studio-2010stlansi-c

Class constructor "C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>"


this is my first post.

I read a lot of topics, and seems I've done all right, but I get the above error again when I try to compile the following code :

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

Could you help me?

Thank you very much!


Solution

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

    The problem is not on the first line, it is on the second line.

    Since member m_oStream is declared as non-reference, the second line above attempts to make a copy of oStream which is not possible, because the copy-constructor of std::ostream is disabled by having made it private, which is what you see in the error message "cannot access private member."

    The fix is this:

    std::ostream * m_oStream; //declare it as pointer.
    bool m_deleteStream;      //flag whether to delete m_oStream or not
    

    Now do this:

    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   
    }
    

    and then you're to write the destructor as:

    ~CLogger()
     {
        if ( m_deleteStream )
        {
            delete m_oStream;
        }
     }
    

    An important point : since this is a resource-managing (logger) class, making it noncopyable would be a good idea, as copying doesn't make sense for logger instances.