尝试将ofstream传递给对象时出错(C ++)

时间:2014-03-24 14:01:45

标签: c++ oop io ofstream

我正在为我的架构类编写一个分支预测器模拟器,我在使用多个类之间的输出工作时遇到了一些麻烦。我正在尝试在main.cpp中打开一个主流,并将其传递给每个类的构造函数以供对象使用。我的头文件中出现了一大堆错误,例如:

In file included from main.cpp:4:0:
predictors.h: In constructor â?~ATPred::ATPred(std::ofstream&)â?T:
predictors.h:14:18: error: use of deleted function â?~std::basic_ofstream<char>& std::basic_ofstream<char>::operator=(
const std::basic_ofstream<char>&)â?T

所以错误似乎出现在我的头文件中:

#ifndef PREDICTORS_H
#define PREDICTORS_H

#include <string>

// Always Taken
class ATPred{
    private:
            std::ofstream outputFile;

    public:
            // Constructor
            ATPred(std::ofstream& file)
            { outputFile = file; }

            // Deconstructor
            ~ATPred()
            {}

            // Member Functions
            void parseResults(std::string filename);
};

// Always Non-Taken
class ANTPred{
    private:
            std::ofstream outputFile;

    public:
            // Constructor
            ANTPred(std::ofstream& file)
            { outputFile = file; }

            // Deconstructor
            ~ANTPred()
            {}

            // Member Functions
            void parseResults(std::string filename);
};

#endif

我不确定我在哪里出错,所以任何帮助都会非常感激。

4 个答案:

答案 0 :(得分:0)

标准C ++流不可复制,并且您按值存储成员outputFile。您必须将其更改为引用或指针。

答案 1 :(得分:0)

这里的问题是您存储ofstream值而不是引用。您可以通过更改ANTPred(以及类似地更改ATPred)来使代码工作,如下所示:

class ANTPred {
private:
    std::ofstream &outputFile;
public:
    ANTPred(std::ofstream &file) : outputFile(file) {
        // other construction work
    }
};

虽然我说这将使您的代码正常工作,但它不一定是安全。存储对ofstream对象的引用隐式地假定它将比所有ATPredANTPred实例更长。如果首先销毁ostream,则ATPredANTPred实例的行为将不确定,并可能导致段错误。

其他选项的非详尽列表包括使用原始指针(导致上面指出的相同生命周期问题),共享指针(c ++ 11 std::shared_ptrboost::shared_ptr或其他一些共享指针库),为每个对象构造一个单独的输出流,或者在需要记录数据时将输出流传递给对象实例。

答案 2 :(得分:0)

不能简单地复制和分配流对象,因为它doesn't make sense to copy a stream

您可以将引用(或[智能]指针)存储到流中,并确保只要您的类存在,对象就不会超出范围(但要注意谁拥有该对象)。

无论如何,如果你确定了,this article提供了复制流的方法,但是......

  

总之,创建流的副本并非易事,而且应该只是   如果你真的需要一个流对象的副本,那就完成了。在许多情况下,   使用引用或指针来流对象更合适   相反,或者在两个流之间共享流缓冲区。

答案 3 :(得分:0)

首先 - 当构造函数的主体运行时,所有成员都应该已经初始化。您只能分配给他们。要初始化成员,您需要使用成员初始化列表:

   struct X {
      int i;
      X() : i(42)  // <-- member initiliazer
      { }
   };

其次 - 无法复制或分配流。

您的选择

  • 有一个引用或指向流的指针作为成员
  • 让类初始化流本身(你的构造函数将采用流的构造函数需要的参数,而不是另一个流)