C++ curious behavior in vector::push_back()

风流意气都作罢 提交于 2020-01-14 05:56:06

问题


I have the following data-structure as a class named "Task":

private:
string name;
int computation_time;
int period;

Furthermore i have a ASCII-File with this content:

A 3 10
B 2 12
C 1 11

name = A, computation_time = 3, period = 10 and so on....

Now i want to read in the file, create Task-object and push it back into a vector:

void read_in_task_list_and_create_tasks(const string &filename, vector<Task> &current_tasks)
{
    ifstream in_file;
    in_file.open(filename.c_str());

    string tmp_name;
    int tmp_computation_time;
    int tmp_period;

    while(!in_file.eof())
    {
        in_file >> tmp_name;
        in_file >> tmp_computation_time;
        in_file >> tmp_period;

//        Task tmp_task(tmp_name, tmp_computation_time, tmp_period);
//        current_tasks.push_back(tmp_task);
        current_tasks.push_back(Task(tmp_name, tmp_computation_time, tmp_period));
    }
}

Now, when i take a look into current_tasks vector, it has elements, but their values dont match my in_file values. Watch the outcommented lines. tmp_task object is exactly correct, but if it's getting pushed back, it loses it's values like descriped above.

Could this be a Copy-Constructor Issue in Task-class, because std::vector is managing the memory-allocation?

I'm using netbeans with g++ compiler on Linux x86.

THX


回答1:


Make sure there are no copy constructors or assignment operators defined.

The automatic ones should do exactly what you want.




回答2:


At least IMO, you're taking somewhat the wrong approach, trying to do too much work yourself. The standard library can already handle most of what you're doing. All you really need to do is specify how to read a single object from the stream:

struct Task { 
    std::string name;
    int computation_time;
    int period;
};

std::istream &operator>>(std::istream &is, Task &t) {
    return is >> t.name >> t.computation_time >> t.period;
}

Then you can use a standard algorithm to actually read the data and put it into your vector:

void read_in_task_list_and_create_tasks(const string &filename, 
                                        vector<Task> &current_tasks) 
{
    std::ifstream in(filename.c_str());

    std::copy(std::istream_iterator<Task>(in), 
              std::istream_iterator<Task>(),
              std::back_inserter(current_tasks));
}

As a bonus, this will also fix the problem you had with seeming to read the last item in the file twice because your loop was wrong (yes, I know you didn't mention that, but based on how you wrote your loop, it's essentially unavoidable).




回答3:


Does Task have the copy constructor and assignment operator defined? When you push the object into the vector it's not pushing that exact one in, it's copying it. So I believe you'll need one of those to be defined (I don't remember which, but it's always good to define both if you define either).



来源:https://stackoverflow.com/questions/4219678/c-curious-behavior-in-vectorpush-back

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!