如何在类中用不同类的对象填充向量

How to fill a vector in class with objects of different class

本文关键字:同类 对象 填充 向量      更新时间:2023-10-16

我正在做一个项目,在这个项目中,我必须创建一个工人类(带有一些基本信息(并将它们全部放在向量中。

我找到了一个适合我的解决方案,但我很好奇有没有更好的方法可以做到这一点?所以,我只是在寻找我的代码的不同实现。

这是我的代码:

#include<iostream>
#include<vector>
#include<string>
#include<iterator>
class worker
{
  private:
    std::string _name;
    int _age;
    double _pay;
  public:
    worker() : _age{0}, _pay{0.0} {}
    worker(std::istream& entry){ input(entry); }
    std::istream& input(std::istream& x){ return x >> _name >> _age >> _pay ; }
    const std::string& get_name() { return _name; }
    const int& get_age(){ return _age; }
    const double& get_pay(){ return _pay;}
};
class vecworkers
{
  private:
    std::vector<worker> vec_workers;
  public:
    void input(std::istream& x)
    {
      worker temp;
      while(temp.worker::input(x))
      vec_workers.push_back(temp);
    }
    void output(std::ostream& x)
    {
      worker temp;
      for( std::vector<worker>::const_iterator it = vec_workers.begin() ; it != vec_workers.end() ; ++it )
      {
        temp = *it ;
        std::cout << temp.get_name() << " "<< temp.get_age() << " " << temp.get_pay() << std::endl;
      }
    }
};
int main()
{
  vecworkers w1;
  w1.input(std::cin);
  w1.output(std::cout);
  return 0;
}

我非常感谢您能提供的任何帮助。

编辑1:你的问题标题有点误导


答:

好吧,既然您标记了 C++11,我假设我可以在这里使用 C++11 功能......所以:

关于代码的一些建议:

  • worker类中的 getter 返回 const reference ,应标记为const函数,因此您有:

    const std::string& get_name() const { return _name; }
    const int& get_age() const { return _age; }
    const double& get_pay() const { return _pay;}
    
  • 同样,返回const int&const double&是没有意义的(尽管我相信优化器会解决这个问题(。

    const std::string& get_name() const { return _name; }
    int get_age() const { return _age; }
    double get_pay() const { return _pay;}
    
  • 您可能需要考虑重载插入和提取运算符<<>>以进行worker。它传达了信息。

  • 除了结束输入循环之外,如何处理基于错误格式的istream故障?你可能要考虑一下。即使没有失败,一个错误的格式也会搞砸整个 vecworker 的输入


  • 第一种选择(没有设计更改,只是清理...但请记住,您必须进行上述const更正才能正常工作(:

class vecworkers
{
  private:
    std::vector<worker> vec_workers;
  public:
    void input(std::istream& x)
    {
        for(worker w; w.input(x); vec_workers.push_back(w));
    }
    void output(std::ostream& x)
    {
        for(const auto& w : vec_workers)
            std::cout << w.get_name() << " " << w.get_age() << " " << w.get_pay() << std::endl;
    }
};
  • 第二种选择(移动印刷责任...或者,如果您要有不同的样式,您可能希望有一个负责打印的类(

class worker
{
  private:
    std::string _name;
    int _age;
    double _pay;
  public:
    worker() : _age{0}, _pay{0.0} {}
    worker(std::istream& entry){ input(entry); }
    std::istream& input(std::istream& x){ return x >> _name >> _age >> _pay ; }
    std::ostream& output(std::ostream& x) const { return x << _name << _age << _pay; }
    const std::string& get_name() const { return _name; }
    int get_age() const { return _age; }
    double get_pay() const { return _pay;}
};
class vecworkers
{
  private:
    std::vector<worker> vec_workers;
  public:
    void input(std::istream& x)
    {
        for(worker w; w.input(x); vec_workers.push_back(w));
    }
    void output(std::ostream& x)
    {
        for(const auto& w : vec_workers)
            w.output(std::cout);    //since you didn't overload insertion operator <<
    }
};

  • 第三种选择?...这对于复合来说是相当微不足道的...因此,通过一些清理,您的解决方案就可以工作了。

出于个人原因,我更喜欢使用指针,超出了您的问题范围。

要简单地添加另一个类的对象(有点误导(,请决定是否希望向量拥有这些对象,请保留指向它们的引用或指针。

在实现中,您创建一个对象,然后将其复制到向量中。

worker temp;
while(temp.worker::input(x))
vec_workers.push_back(temp);

按住指针是一种不同的方法:

auto tmp = std::unique_ptr<worker>(new worker(x));
vec_workers.push_back(std::move(tmp));

在这里,你在堆上分配一次,并持有指向它的指针(向量拥有它(。共享/智能指针或多或少的方法相同。

引用有点棘手,需要使用std::reference_wrapper

您也可以立即简单地复制矢量中的对象。

workers.push_back(std::move(worker(x));

或者使用原始指针std::vector<worker*> workers;

正如我在这里看到的,对象不属于不同的类,或者我弄错了。

它们可能具有不同的构造函数,但仍然没有不同的类。

对类型使用特定的向量类有点没用,但我想更具可读性。

您不能创建多个类的向量,因为由于向量语法,这是不可能的。

如您所见,您使用

    vector <type>

    vector <type,...>

因此,您只能拥有单一类型的向量。

此外,如果你可以制作多个类的向量,那会搞砸大小,因为它会根据你放入的对象类别而增加不同的量。

您需要使用多态性和继承才能使其正常工作。从技术上讲,不同类型的对象不能添加到向量中,但继承和多态性可以使其看起来像这样。

所以你可以有一个这样的向量

vector<BaseClass*> vec;

并将派生类的对象推送到它。 许多现代编程语言的所有类都派生自一个公共的"对象"类,以使这个和其他事情成为可能。