使用作为类成员的流写入文件

时间:2014-09-15 18:31:29

标签: c++ filestream

我想写一个具有ofstream作为成员的类的文本文件。怎么做?为什么以下不起作用?

#include <fstream>

class A {
public:

A(char const* file);
A(A&);
void operator = (A&);
void writeTofile();
std::ofstream stream;
};

A::A(char const* file): stream(file)
{
stream.open(file);
stream << "Hello World!" << std::endl;
stream.close();
}
void A::writeTofile()
{
stream << "Hello Again!"  << std::endl;
}

int main()
{
char const* file = "foo.txt";
A a = A(file);
a.writeTofile();
return 0;
}

3 个答案:

答案 0 :(得分:1)

你有两个问题:

  1. 您在进一步输入所需的文件流上调用close()

    A类的构造函数打开文件,将"Hello, World"写入标准输出,然后关闭文件。之后调用writeToFile()时,文本无法写入文件,因为文件已被关闭。

    您无需以任何方式在文件流上显式调用close(),因为当流超出范围时,流的析构函数将自动关闭文件。除非您要打开具有不同名称的文件,否则无需手动执行此操作。

  2. 无法复制流。

    这段代码:

    A a = A(file);
    

    执行复制初始化。它与直接初始化(A a(file))不同,它通过复制其初始化程序的右侧来初始化对象。选择执行此副本的构造函数取决于右侧的类型和可行构造函数的可用性。

    通常复制构造函数将用于此类复制(编译器默认为您提供一个),但由于您提供了自己的构造函数A::A(A&),因此它禁止创建编译器生成的副本 - 构造函数。 AA(file))的临时实例无法转换为对A的引用(C ++中的查找引用)。对于您提供的其他构造函数也是如此,没有从Aconst char*的转换。

    如果删除自定义构造函数,您仍会发现错误。这是因为无法复制C ++ IOStream对象(它们具有“已删除”的复制构造函数)。因此,由于std::ofstream是类的成员,因此该类也具有已删除的复制构造函数。

    有两种解决方案:

    • 提供您自己的副本构造函数,它什么都不做。
    • 使用直接初始化(即A a(file)

答案 1 :(得分:0)

您在A的构造函数中关闭了流,因此它不再接受任何输入

A::A(char const* file): stream(file)
{
    ...
    stream.close();
}

尝试将其移至析构函数:

A::~A()
{
    stream.close();
}

答案 2 :(得分:0)

您的问题是您在A的构造函数中关闭了流,因此当在writeToFile()中访问它时,流已关闭,并且不再接受任何输入。

尝试将stream.close();移动到析构函数,你应该没问题:

A::~A()
{
    stream.close();
}