1

In advance: I'm new to C++, so please be kind. ;-)

I'm trying to add several Objects (Result) to a vector (results), but somehow it doesn't work the way i want.^^

UPDATE: I changed the code a little and showed some more code for more information

//file1
class Result{
public:
    Result(string rtype, string rname, double rcosts){
        type = rtype; name = rname; costs = rcosts;
    }
private:
    string type, name; double costs;
};

//file2
void getCosts(vector<Parts> parts){
    vector<Part *> p;
    for(unsigned i = 0; i < parts.size(); i++){
        p.push_back(&parts[i]);
    }
    cout << p.at(0)->getName() << p.at(0)->getPrice << endl;  //this output is correct
    cout << p.at(0)->getName() << p.at(0)->getPrice << endl;  //this output is correct
    cout << p.at(0)->getName() << p.at(0)->getPrice << endl;  //this output is correct

    vector<Result *> r;
    for(std::vector<Part *>::iterator ip = p.begin; ip != p.end(); ip++){
        addResult((*ip)->getType(), (*ip)->getName(), r, (*ip)->getPrice());
    }
    sortAndPrintResults(r);
    //after this method printed the results into a file the programm ends. so the scope shouldn't matter. (getCosts is only called once)
}

void addResult(string type, string name, vector<Result *> results, double costs){
    Result * res = new Result(type, name, costs);        
    results.push_back(res);
    cout << res->getName() << endl; //this prints the name of every object
}

The output should be as follows:

abc //results.at(0)
def //results.at(1)
ghi //results.at(2)

But instead it's:

abc //results.at(0)
def //results.at(0)
ghi //results.at(0)
error: out of range. //results.at(1)
error: out of range. //results.at(2)

What am i doing wrong?

mäx
  • 23
  • 3

2 Answers2

2

The issue is in your debugging.

This code adds a single, then expects three.

void addResult(string type, string name, vector<Result *> results, double costs){
    results.push_back(new Result(type, name, costs));
    cout << results.at(0)->getName() << endl;
    cout << results.at(1)->getName() << endl;
    cout << results.at(2)->getName() << endl;
}

You want to call addResult 3 times before outputting.

In this case, you want to put it after your forloop in getCosts:

void getCosts(vector<Parts *> p){
    for(std::vector<Part *>::iterator ip = p.begin; ip != p.end(); ip++){
        addResult((*ip)->getType(), (*ip)->getName(), r, (*ip)->getPrice());
    }
    //Check results here.
}

Edit: As CaptainObvlious mentioned, you're also passing the vector by-value into the addResult function.

Adding by-value means a vector<Result *> is created locally within the function, and doesn't connect back to the r variable you passed in (hence when you try to r.at(0), there's nothing inside)

Fixing this is fairly straight forward, to link the function-parameter results to your r vector, you need to pass it by-reference, which is as simple as prepending the type with '&':

void addResult(string type, string name, vector<Result *>& results, double costs)

Have a read up of by-value vs by-reference.

Community
  • 1
  • 1
Jono
  • 3,949
  • 4
  • 28
  • 48
  • Yeah, the first thing makes sense.^^ but when i put 'cout' right after the loop, even results.at(0) results in an out of range error. – mäx Jun 18 '14 at 12:26
  • 1
    @max This is because you are passing the vector by value instead of by reference or pointer. When you return from `getCosts` the vector `p` is destroyed and the modifications are not reflected in the function that called it. Try `void getCosts(vector& p)` instead. @Jono feel free to incorporate this into your answer if it is in fact the OP's problem. – Captain Obvlious Jun 18 '14 at 12:31
  • 1
    @jono: it worked! thank you very much! and the rest of you as well, of course! – mäx Jun 18 '14 at 13:33
0

I noticed a few errors in your code, please try the following:

//file1
class Result{
public:
    Result(string rtype, string rname, double rcosts){
        type = rtype; name = rname; costs = rcosts; //changed to actually assign to member
    }
private:
    string type, name; double costs;
};

//file2 - you did not show where you got the 'r' parameter from
void getCosts(vector<Parts *> p){
    for(std::vector<Part *>::iterator ip = p.begin; ip != p.end(); ip++){
        addResult((*ip)->getType(), (*ip)->getName(), r, (*ip)->getPrice());
    }
}

void addResult(string type, string name, vector<Result *> & results, double costs){
    Result * res = new Result(type, name, costs);
    results.push_back(res);
    cout << res->getName() << endl;
}