2

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!

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
Antonio Petricca
  • 8,891
  • 5
  • 36
  • 74

2 Answers2

6
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.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
0

In

m_oStream(ofstream(sFileName.c_str()))

you construct an ofstream and copy-construct your m_oStream with it. Just write

m_oStream(sFileName.c_str())

Streams are neither copy-constructible nor copy-assignable, though they are movable types, so I guess your are not using C++11 in this example.

For the same reason,

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

is not going to work. You cannot make copies, you can only move (in C++11) or hold a reference of some form.


Sidenote:

From your example this is not entirely clear whether you did so, but don't forget include guards in your header file.

Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130