为什么header中的全局变量ofstream不能用C++写文件?

Why global variable ofstream in header can't write files in C++?

1.For例如,有a.cpp, b.h, b.cpp b.h

b.h:

#ifndef UNTITLED_B_H
#define UNTITLED_B_H
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
class b {
    ofstream b_out; // here
public:
    explicit b();
    int b_write(const string &message);
};
#endif //UNTITLED_B_H

b.cpp:

#include "b.h"
b::b(){        
    b_out.open("test.txt");
}
int b::b_write(const string &message){
    b_out<<message;
}

a.cpp:

#include "b.h"
int main(){
    b *b_object = new b();
    b_object->b_write("hello happy b");
}

此代码没有错误,文件已创建。 但未打印消息。

但是,将 ofstream 定义代码(//此处标记)带到 b.cpp,如下所示。

b.h:

#ifndef UNTITLED_B_H
#define UNTITLED_B_H
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
class b {
public:
    explicit b();
    int b_write(const string &message);
};
#endif //UNTITLED_B_H

b.cpp:

#include "b.h"
ofstream b_out; //here
b::b(){
    b_out.open("test.txt");
}
int b::b_write(const string &message){
    b_out<<message;
}

在这种情况下,消息打印得很好。

但我不明白它们之间的区别。

谁能帮帮我?

谢谢!

您在堆上创建 b 的实例

b *b_object = new b();

这意味着当您不再使用它时,您有责任将其删除

b* b_object = new b();
/* use b_object here */
delete b_object;

如果不调用 delete,则不会调用析构函数,这意味着不会调用 ofstream 的析构函数,这会在流上调用刷新,将消息写入文件。当您在 b.cpp 中将 ofstream 实例创建为全局实例时,编译器负责调用它的析构函数,这就是它起作用的原因。

不要自己管理内存,使用智能指针

#include <memory>

auto smart_ptr = std::make_unique<b>();
smart_ptr->b_write("hello happy b");

它将为您调用 delete

更好的是,如果您在堆栈上创建 b 的实例,编译器会为您做所有事情,这要感谢 RAII。

int main(){
    b b_object;
    b_object.b_write("hello happy b");
}