vendredi 15 juillet 2022

Initializing std::ofstream object in header file v/s source file

I came across some weird compilation error related to std::ofstream. Let's say, I have one header file ofstream_test.hpp, and its corresponding source file ofstream_test.cpp.

ofstream_test.hpp:

#include <iostream>
#include <fstream>

class OfstreamTest {
public:
    OfstreamTest();

    std::ofstream m_strm_obj("output.txt");
};

ofstream_test.cpp:

#include "ofstream_test.hpp"

OfstreamTest::OfstreamTest() {
    std::cout << "ctor" << std::endl;
}

main.cpp:

#include "ofstream_test.hpp"

int main(int argc, char const *argv[]) {
    OfstreamTest obj;
    return 0;
}

The error:

$ g++ -std=c++17 main.cpp ofstream_test.cpp 
In file included from main.cpp:1:0:
ofstream_test.hpp:8:30: error: expected identifier before string constant
     std::ofstream m_strm_obj("output.txt");
                              ^~~~~~~~~~~~
ofstream_test.hpp:8:30: error: expected ‘,’ or ‘...’ before string constant
In file included from ofstream_test.cpp:1:0:
ofstream_test.hpp:8:30: error: expected identifier before string constant
     std::ofstream m_strm_obj("output.txt");
                              ^~~~~~~~~~~~
ofstream_test.hpp:8:30: error: expected ‘,’ or ‘...’ before string constant

If I try to use the open method, I also get the compilation error (a bit different though):

ofstream_test.hpp:

class OfstreamTest {
public:
    OfstreamTest();
    std::ofstream m_strm_obj;
    m_strm_obj.open("output.txt");
};

ofstream_test.cpp:

OfstreamTest::OfstreamTest() {
    std::cout << "ctor" << std::endl;
}

The error:

$ g++ -std=c++17 main.cpp ofstream_test.cpp 
In file included from main.cpp:1:0:
ofstream_test.hpp:9:5: error: ‘m_strm_obj’ does not name a type
     m_strm_obj.open("output.txt");
     ^~~~~~~~~~
In file included from ofstream_test.cpp:1:0:
ofstream_test.hpp:9:5: error: ‘m_strm_obj’ does not name a type
     m_strm_obj.open("output.txt");
     ^~~~~~~~~~

However, for the following cases, I'm not getting any compilation error:

  • Case 1:

ofstream_test.hpp:

class OfstreamTest {
public:
    OfstreamTest();
};

ofstream_test.cpp:

OfstreamTest::OfstreamTest() {
    std::cout << "ctor" << std::endl;
    std::ofstream m_strm_obj("output.txt");  // initialized the object in source file, instead of header file
}
  • Case 2:

ofstream_test.hpp:

class OfstreamTest {
public:
    OfstreamTest();
    std::ofstream m_strm_obj{"output.txt"};  // just changed () to {}
};

ofstream_test.cpp:

OfstreamTest::OfstreamTest() {
    std::cout << "ctor" << std::endl;
}
  • Case 3:

ofstream_test.hpp:

class OfstreamTest {
public:
    OfstreamTest();
    std::ofstream m_strm_obj;  // declared the object but didn't initialize in the header file
};

ofstream_test.cpp:

OfstreamTest::OfstreamTest() {
    std::cout << "ctor" << std::endl;
    m_strm_obj.open("output.txt");
}

I don't understand why?

Would greatly appreciate an in-depth answer (or at least an answer with some reference links)!

Aucun commentaire:

Enregistrer un commentaire