1

I'm having issues declaring a constructor of an inherited class.

class Report{
public:
    string fileName;
    std::ofstream outputFile;

    Report(string fileName, ofstream outputFile) {

        fileName = fileName;
        outputFile = outputFile; //<-- error here
    }

    void returnFile(string, ofstream);

    void Report::returnFile(string name, ofstream file){

         file.open(name);
    }
};

class financialReport: public Report{
public:
    void electorateHappenings();
    void electorialImpact();
    double finances();
    void writetoFile();

    financialReport(string fileName, ofstream outputFile)
    :Report(fileName, outputFile) { } //<-- error here
};

the error occurs on the 3rd last line :Report(fileName, outputFile).

This line produces the error:

function "std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const
 std::basic_ofstream<_CharT, _Traits> &) [with _CharT=char, 
_Traits=std::char_traits<char>]" (declared at line 848 of 
"C:\MinGW\lib\gcc\mingw32\9.2.0\include\c++\fstream") cannot be referenced 
-- it is a deleted function

Is it not possible to create a constructor including ofstream?

The error also occurs on line 9 with outputFile = outputFile.

Thank you.

anastaciu
  • 23,467
  • 7
  • 28
  • 53
Bao Ling
  • 69
  • 7

2 Answers2

2

You can't pass it by copy, you can't copy one, but you can pass it by reference and initialize it in the initializer list of the class:

Demo

class Report {
public:
    string fileName;
    std::ofstream &outputFile; //reference here

    // reference parameter, and initializer list
    Report(string fileName, ofstream &outputFile) : outputFile(outputFile) {
        fileName = fileName;
    }
    //...
};

Do the same in financialReport:

financialReport(string fileName, ofstream& outputFile) : Report(fileName, outputFile) {}
                                         ^

Note that this is a solution to the problem posed in the question, as normal, but in a more deep analysis, though you don't go in detail about what you want to achieve, I wouldn't go so far as to say it's a wrong approach, but odds are you can structure your program in a better way.

anastaciu
  • 23,467
  • 7
  • 28
  • 53
2

Yes, you can, but the error is telling you that you cannot copy an object of std::ofstream.

Depending on what you want to do, there are two ways to handle it.

Pass the ownership of std::ofstream to your newly created object:

Report(string fileName, ofstream outputFile) :
    fileName{std::move(outputFile)},
    outputFile{std::move(outputFile)}
{
}

//creation of object:
std::ofstream ofs {"filename.txt"};
Report report {"filename.txt", std::move(ofs)};
//ofs is empty here, it's whole content has been transferred to report object

Pass a reference to existing std::ofstream object:

class Report{
public:
  string fileName;
  std::ofstream& outputFile;

Report(string fileName, ofstream& outputFile) :
    fileName{std::move(outputFile)},
    outputFile{outputFile}
{
}

//creation of object:
std::ofstream ofs {"filename.txt}";
Report report {"filename.txt", ofs};
//you can use ofs from both here and from inside of report, but 
//you have to ensure that ofs lives as long as report will use it or else you will enter Undefined Behaviour land

Note: If you want to have the same names for class members and for constructor arguments, you need to use member initializer list, like I did. If you decide to use references, you are required to use it as well.

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52