首页 > 解决方案 > 在设计方面:为向量类型的类成员重载插入运算符

问题描述

尝试从源文件中读取以将人员对象存储到容器中。

一个人对象用一个随机的年龄、id 和一个由五个不同字符组成的类别向量进行初始化。

人.hpp

class person 
{
    protected :
    int age; // 0 - 99
    int id;  // 20181104 eight numeric characters 
    std::vector<char> categories = {'A', 'B', 'C', 'D', 'E'}

    person()
    {
    ...
    std::shuffle(categories.begin(), categories.end(), 
      random_generator::instance().gen);
    }
}; 

random_generator.hpp

用于使用 std::shuffle 对人员类成员类别进行洗牌

class random_generator
{
    public :
        static random_generator& instance()
        {
            static random_generator instance;
            return instance;
        }
        random_generator(random_generator const&)            = delete;
        random_generator& operator=(random_generator const&) = delete;
    private :
        random_generator(){}
        std::random_device rd;
        std::mt19937 gen{rd()};

    ...
    friend class person;
};

个人.cpp

std::ostream& operator<<(std::ostream& output, const person& p)
{
  output << p.id <<  ' ' << p.age; 

  for(char c : p.categories)
    output << c << ' ';

  return output;
}
std::istream& operator>>(std::istream& input, person& p)
{
  input >> p.id >> p.age;

  // how can I implement this; suggested alternatives are most welcome

  return input;
}

person.txt 源文件

19850319 33 ACEBD
06111990 28 BECAD

标签: c++oopvectoristreamistringstream

解决方案


我想我看不出困难在哪里。读入它们将是写出它们的镜像。如果您可以指望它们总是有五个,那么您基本上只需执行以下操作:

std::istream& operator>>(std::istream& input, person& p)
{
  input >> p.id >> p.age;

  p.categories.clear();
  for (int i=0; i<5; i++) {
     char ch;
     input >> ch;
     p.categories.push_back(ch);
  }

  return input;
}

如果基本上是在到达行尾之前读取类别的问题,那么将行读入字符串,将字符串推入字符串流,然后读取字符直到到达字符串流的末尾可能是最简单的:

while (input >> ch)
    p.categories.push_back(ch);

这通常不是最快的处理方式(创建字符串流有点慢),但考虑到您正在处理 I/O,解析速度很少成为考虑因素。


推荐阅读