0

There is a function that prints something and I need to call this function both explicitly in the main as well as in the destructor when the object (has to be a global one) is destroyed. However the destructor's call doesn't display in the file.

#include <iostream>
#include <fstream>

using namespace std;

class A {

public:
    friend void func(A&);
    ~A() {
        func(*this);
    }

};

A a;
ofstream out;

int main() {
    out.open("file.txt");
    func(a);
    cin.get();
    return 0;
}

void func(A& a) {
    out << "\nHello!!!\n";
}

I only see one "Hello!!!" in the file when I want two. I also haven't closed the ostream object either. Ideally, I'd want to close it after the function call in the destructor. How do I do it?

B-Mac
  • 557
  • 2
  • 14
  • 2
    Considering it's already closed before the destructor call, there's not much point in closing it again. Anyway, are you sure what you're actually trying to do requires these strange semantics that arise only with global variables? – chris Apr 26 '15 at 18:21
  • @chris: Trust me, I need to go this way buddy. – B-Mac Apr 26 '15 at 18:25
  • @chris: How is it getting closed before destructor call? We haven't really used `out.close()` anywhere. – B-Mac Apr 26 '15 at 18:25
  • The fundamental C++ way of doing things is to clean up in destructors so that you don't *have* to remember to explicitly clean up after that object. The file stream gets destroyed and it closes itself. – chris Apr 26 '15 at 18:32
  • Ok, I know this is not ideal but let's say I have been ordered by a lunatic boss to call a function in a destructor that writes something onto a file. How do I do it in a better way? – B-Mac Apr 26 '15 at 18:34
  • Sounds like the class could have the file stream (or the more general `std::ostream` so the user can choose where it should write to) as a member. – chris Apr 26 '15 at 18:36
  • Hmmm...anyway, appreciate your advice. Will implement it and check. – B-Mac Apr 26 '15 at 18:40

1 Answers1

1

Static objects in the same translation unit are constructed in the order of their definition and destructed in reverse order, as explained here

As such, your "out" object gets destructed(and therefore closed) before a's destructor is called and tries to write to it.

Switching the declaration order fixes the problem, but is propably not a great solution and you would be better of avoiding the static, global objects alltogether. (Especially try to avoid depending on the order of their destruction).

Community
  • 1
  • 1
Philipp Lenk
  • 921
  • 6
  • 14
  • Then how do you suggest I go about it? The only criteria is that the function must be called through a destructor and that function must write something onto a file. – B-Mac Apr 26 '15 at 18:29
  • 2
    If you absolutely have to have a global object and that objects destructor has to write to resource owned by another global object, switch the declaration order, as mentioned above. But note that such design is seriously flawed. If your assignment forces you to just one global object, I suggest you follow chris advice in the comments to your question and make out a member of A – Philipp Lenk Apr 26 '15 at 18:39