使用助手类接口写入文件,在哪里打开流

Writing to a file using a helper class interface, where do I open the ofstream?

本文关键字:文件 在哪里 接口      更新时间:2023-10-16

这是一个很难放在一个标题中的问题。因此,我尝试使用FileIO类的成员函数将Account类中包含的数据写入文件。FileIO是Account类的复合成员数据对象。我有3个Account对象存储在一个指针向量中,我正在循环这些指针,将它们全部写入一个文件。我想知道如何使用WriteData()函数来查看打开的文件?我无法在函数本身中打开文件,因为我需要在关闭文件之前将所有Account对象写入文件

这是我的代码:

class FileIO
{
private:
    ofstream _accoFile;
public:
    FileIO();
    ~FileIO();
    void WriteData(Account*);
    ofstream& GetoStream();
};
void FileIO::WriteData(Account* acc)
{
    _accoFile << acc->GetAccNum() << "n" << acc->GetAccOwner()->GetName() << "n" << acc->GetAccOwner()->GetAddress() << "n" << acc->GetAccBal() << "n";
    //acc->WriteAcc(_accoFile);
}
class Account
{
private:
    Person* _accOwner;
    int _accNumber;
    double _accBalance;
    FileIO* _iFile;
public:
    Account();
    ~Account();
    Account(Person*, int, double);
    Person* GetAccOwner();
    int GetAccNum();
    double GetAccBal();
    FileIO* GetiFile();
};

主要:

FileIO* test = new FileIO();
    test->GetoStream().open("accInfo.txt");
    for (int i = 0; i < accountsVec.size(); i++) {
        accountsVec[i]->GetiFile()->WriteData(accountsVec[i]);
    }
    test->GetoStream().close();

让你很难回答问题的是,真正的问题在其他地方:

FileIO是Account类的复合成员数据对象。

为了适当地分离责任,FileIO不应该是Account的成员

相反,它应该是一个单独的类。使用这种SOLID类型的设计,打开流的问题很容易解决,因为这可以在构造函数中完成:

class FileIO
{
private:
    ofstream _accoFile;
public:
    FileIO(const std::string& filename) : _accoFile(filename) {};
    void WriteData(Account*);
};

采用这种设计:

  • 一旦创建了FileIO的实例,就会打开输出文件
  • Account的几个实例可以被序列化到同一个输出文件中
  • 一旦FileIO实例被销毁,输出文件就会自动关闭

下面是一个简单的main演示如何使用这样的串行器:

int main()
{
    std::vector<Account*> accountsVec;
    FileIO writer("accInfo.txt");
    for (int i = 0; i < accountsVec.size(); i++) {
        writer.WriteData(accountsVec[i]);
    }
    return 0;
}

更新

我理解该分配要求为所有Account实例提供一个通用的成员序列化程序。这真的很奇怪,所以可能值得仔细检查。无论如何,以下是我可以根据这些奇怪的要求想出的办法。

串行器可以用典型的I/O openclose方法设计:

class FileIO
{
private:
    ofstream _accoFile;
public:
    void open(const string& filename) { _accoFile.open(filename); }
    void close()                      { _accoFile.close();        }
    void WriteData(Account*);
};

由于串行器是Account的复合成员,因此应将其集成到Account ctor:中

Account::Account(Person* accOwner,int accNumber,double accBalance,FileIO* iFile) 
: _accOwner(accOwner), _accNumber(accNumber), _accBalance(accBalance), _iFile(iFile)
{}

如果Account负责将自己保存到目标文件中,那么最好编写一个实现该职责的Account方法:

void Account::WriteData()
{ 
    _iFile->WriteData(this); 
}

以下是基于此设计的main示例:

int main()
{
    FileIO fileio;
    Person person1{"toto","Paris"};
    Person person2{"tutu","London"};
    Person person3{"tata","Lisboa"};
    vector<Account> accountsVec;
    accountsVec.emplace_back( &person1 , 1,   12., &fileio );
    accountsVec.emplace_back( &person2 , 2,  100., &fileio );
    accountsVec.emplace_back( &person3 , 3, 1000., &fileio );
    fileio.open("accInfo.txt");
    for (int i = 0; i < accountsVec.size(); i++) {
        accountsVec[i].WriteData();
    }
    fileio.close();    
}