0

I am getting this error when trying to compile my code:

1>  c:\mingw\bin\../lib/gcc/mingw32/4.6.2/include/c++/ostream: In constructor 'Log::Log(const char*)':
1>c:\mingw\bin\..\lib\gcc\mingw32\4.6.2\include\c++\ostream(363,7): error : 'std::basic_ostream<_CharT, _Traits>::basic_ostream() [with _CharT = char, _Traits = std::char_traits<char>]' is protected
1>C:\Users\Adam\Documents\cs\cs176b\hw2\ftp\ftp\log.cpp(6,26): error : within this context

Not really sure why, I didn't make the ostream code I am using myself, I used what was suggested here: Proper way to create ostream to file or cout

My code is below, happy to give any more info if needed:

// log.h
#include <string>
#include <fstream>

#ifndef LOG_H_
#define LOG_H_

class Log 
{
    public:
        enum Mode { STDOUT, FILE };

        // Needed by default
        Log(const char *file = NULL);
        ~Log();

        // Writing methods
        void write(char *);
        void write(std::string);
    private:
        Mode mode;
        std::streambuf *buf;
        std::ofstream of;
        std::ostream out;
};

#endif


// log.cpp
#include "log.h"
#include <iostream>
#include <stdlib.h>
#include <time.h>

Log::Log(const char *file)
{
    if (file != NULL)
    {
        of.open(file);
        buf = of.rdbuf();
        mode = FILE;
    }
    else
    {
        buf = std::cout.rdbuf();
        mode = STDOUT;
    }

    // Attach to out
    out.rdbuf(buf);
}

Log::~Log()
{
    if (mode == FILE)
        of.close();
}

void Log::write(std::string s)
{
    out << s << std::endl;
}

void Log::write(char *s)
{
    out << s << std::endl;
}
Community
  • 1
  • 1
MasterGberry
  • 2,800
  • 6
  • 37
  • 56

2 Answers2

4

std::ostream::ostream() constructor is protected, which means it can only be invoked by its derived class, but not but its enclosing one.

To fix the error initialize member out.

The only public constructor of std::ostream accepts a std::streambuf*, e.g.:

Log::Log(const char *file)
    : out(std::cout.rdbuf())
// ...

Note, that it is safe to initialize a std::ostream with the buffer from std::cout.rdbuf(), because destructor std::ostream::~ostream() does not deallocate its std::streambuf* member.

Alternatively, it can be initialized with a NULL/nullptr. In this case be careful to not output anything into the stream as it would try dereferencing that NULL leading to undefined behaviour, most likely just crash with SIGSEGV.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
0

In extension to what David said:

ostream is just the "frame" of an output stream, a definition of basic capabilities of an output stream (abstract class). It does nothing and is not implemented.

Did you try to write to cout perhaps? cout is defined in iostream, you do not need to define it, just use it!

TheRealISA
  • 113
  • 6