【问题标题】:Fail to use iterator to read a vector in the vector of class object使用迭代器读取类对象向量中的向量失败
【发布时间】:2019-08-06 09:21:39
【问题描述】:

我在类对象的向量内创建了一个向量。 数据层次结构如下:

ServerList {
       ConsolePerformance: {
               Name:Computer1
               DelayTime:{12, 14, 16, 19}
               ProcessTime:{100, 210, 20, 40}
       },
       {       
               Name:Computer2
               ...
       }
       ...
}

类对象ServerList包含一个ConsolePerformance类对象的向量。

每个 ConsolePerformance 类对象都有一个 DelayTime 向量和一个 ProcessTime 向量。

一台计算机上运行着四个进程,因此 DelayTime 和 ProcessTime 将包含四个值。

我要找出向量内的最大值/最小值。

我可以通过我的类对象的get方法正确读取向量中的一个值。

但是,我无法使用迭代器读取值。有没有我设置错误的声明?

这是我的代码:

服务器列表.h

class ServerList {
    private:
        vector<ConsolePerformance*> performanceStat;
    public:
        ServerList();
        vector<ConsolePerformance*> & getPerformanceStat() {return performanceStat;}
};

ServerList::ServerList() {
    ConsolePerformance *cp1 = new ConsolePerformance();
    cp1->setName("Computer1");
    performanceStat.push_back(cp1);

    ConsolePerformance *cp2 = new ConsolePerformance();
    cp2->setName("Computer2");
    performanceStat.push_back(cp2);
}

ConsolePerformance.h

class ConsolePerformance {
    private:
        string Name;
        vector<float> delayTime, processTime;
    public:
        string getName() const {return Name;}
        vector<float> getDelayTime() const {return delayTime;}
        vector<float> getProcessTime() const {return processTime;}

        void setName(string _s) {Name = _s;}
        void addDelayTime(float _i) {delayTime.push_back(_i);}
        void addProcessTime(float _i) {processTime.push_back(_i);}
}

Main.cpp

int main()
{
    ServerList LE = ServerList();

    float performanceTime = 12; //repeat for 14, 16, 19
    LE.getPerformanceStat()[0]->addDelayTime(performanceTime);
    performanceTime = 14; 
    LE.getPerformanceStat()[0]->addDelayTime(performanceTime);
    performanceTime = 16; 
    LE.getPerformanceStat()[0]->addDelayTime(performanceTime);
    performanceTime = 19; 
    float performanceTime = 100; //repeat for 210, 20, 40
    LE.getPerformanceStat()[0]->addProcessTime(performanceTime);
    performanceTime = 210; 
    LE.getPerformanceStat()[0]->addProcessTime(performanceTime);
    performanceTime = 20; 
    LE.getPerformanceStat()[0]->addProcessTime(performanceTime);
    performanceTime = 40; 
    LE.getPerformanceStat()[0]->addProcessTime(performanceTime);
        //...

        cout << LE.getPerformanceStat()[0]->getDelayTime()[0]; //show 12 correctly

        //Iterator here return something like 4.80697e-039
        std::vector<float>::iterator itr = LE.getPerformanceStat()[0]->getDelayTime().begin();
        std::vector<float>::iterator itr2 = LE.getPerformanceStat()[0]->getDelayTime().end();
        vector<float>::iterator ptr;
        for(ptr=itr ; ptr!=itr2 ; ptr++)
                cout << *ptr << endl;

        //The following would prompt out Access violation reading location
        //auto result = std::minmax_element (LE.getPerformanceStat()[i]->getDelayTime().begin(),LE.getPerformanceStat()[i]->getDelayTime().end());
}

【问题讨论】:

  • 如果你返回一个对它的非常量引用,那么创建performanceStat private 是没有意义的。
  • 不使用vector&lt;ConsolePerformance&gt;的任何具体原因(注意:没有指针)?
  • 良好的做法是尽可能保持变量范围为本地。在循环之后你还需要ptr 吗?如果没有,最好写for(auto ptr = ...
  • 如果使用vector&lt;ConsolePerformance&gt;,addDelayTime、addProcessTime不会更新delaytime和processtime。 (因为它不是通过引用传递的?)
  • ptr 循环对我来说只是一个测试代码,表明我创建的迭代器存在问题。无需使用。

标签: c++ class vector


【解决方案1】:

问题在于返回类型为 getDelayTime。你返回一个vector的副本,所以调用begin/end引用两个不同的对象,它导致UB。

通过引用返回向量:

    const vector<float>& getDelayTime() const {return delayTime;}
    const vector<float>& getProcessTime() const {return processTime;}

这些方法是 const 限定的,所以你需要返回对 const 向量的引用。

如果您不想更改类的接口,请创建一个向量副本,然后在其上调用begin/end

std::vector<float> v = LE.getPerformanceStat()[0]->getDelayTime();
auto itr = v.begin();
auto itr2 = v.end();

【讨论】:

  • 需要const返回类型以及编译
猜你喜欢
  • 1970-01-01
  • 2015-07-31
  • 2017-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-25
  • 1970-01-01
相关资源
最近更新 更多