Vector of objects

Hey ya'll I'm new to vectors and I have created a class of PaintJobContracts, which should have fields for a customer's name, job number, and amount owed. I went ahead and created my class with no issues, but I got stuck in my main file when I tried to create a function that is supposed to prompt the user for info and store it into the vector after validation.

This is the error I am receiving "error: no matching function for call to ‘std::vector::push_back(std::string&)", when I try to do this:

1
2
3
4
5
6
7
8
9
10
11
12
13
//this is a function from my main file. I have a switch(for the user to select a menu choice)
// and I'm calling this function when the user selects the menu choice

void addCustomer(vector<PainterJobContracts> contract)
{
    string userInput;
    //prompt user to enter name
    cout<<"enter you first and last name"<<endl;
    //read in name
    getline(cin,userInput);
    contract.push_back(userInput);
            
}


Please correct me if I'm wrong, but am I getting this error because the vector expects an object and not a string? If this is the case, how can I get what I've prompted the user to enter to be stored as an object attribute in the vector?
Last edited on
> cout<<"enter you first and last name"<<endl;
...
> which should have fields for a customer's name, job number, and amount owed.
So are you going to input the rest of the information?

At some point, you need to make a new object instance as you surmised.
1
2
3
// just guessing what you need to construct this with
PainterJobContracts newjc(name,jobNo,owed);
contract.push_back(newjc);



> void addCustomer(vector<PainterJobContracts> contract)
This is a copy of your vector, so any changes you make will be lost when the function returns.
So you need to make it a reference.
void addCustomer(vector<PainterJobContracts> &contract)



yes, I will be entering the info. In main, I created a vector of PainterJobContracts and when I select addCustomer, I should be prompted to enter the info required, which should then be stored in the vector. I hope that makes sense.

I did this a couple weeks ago using arrays, I would just prompt the user and use my setters to set the user input to the array.
Something like this:
arr[objInArr].setCustomerName(userInput);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
PainterJobContracts plain[42]; // has 42 default constructed PainterJobContracts elements
vector<PainterJobContracts> empty; // has array of 0 elements
vector<PainterJobContracts> other(42); // has array of 42 default constructed PainterJobContracts elements

PainterJobContracts con; // default constructed PainterJobContracts
empty.push_back( con ); // copy constructs PainterJobContracts element
// more familiar copy construction:  PainterJobContracts tract( con ); ?

// if you can construct a PainterJobContracts from string,
// i.e. there is PainterJobContracts( const string& );
// then:
string words( "Hello world" );
PainterJobContracts sample( words ); // calls PainterJobContracts( const string& );

// and also:
empty.emplace_back( words ); // calls PainterJobContracts( const string& ); 

If you can't create contracts from string, then:
1
2
3
4
getline( cin, userInput );
PainterJobContracts input;
input.setCustomerName(userInput); 
contract.push_back( input );



Functions take parameters by value or by reference. Parameters are essentially local variables of the function that are initialized in the function call.
1
2
3
4
5
6
7
void sample( PainterJobContracts one, PainterJobContracts& two );
PainterJobContracts input;

sample( input, input );
// function call essentially does:
PainterJobContracts  one = input; // copy construction
PainterJobContracts& two = input; // create reference 

A plain array is passed by value, but with a huge twist. Function does not get an array. The array is not copied at all.
1
2
3
void addCustomer( PainterJobContracts contract[] );
// is same as
void addCustomer( PainterJobContracts* contract );

Function does not get copy of array. Function gets pointer to array.
1
2
3
4
5
6
PainterJobContracts plain[42];
addCustomer( plain );
// is effectively same as:
PainterJobContracts plain[42];
PainterJobContracts* temporary = plain; // implicit conversion from array to pointer
addCustomer( temporary );


The vector is an object. It has copy constructor that copies values of the array that the vector has.
Therefore, by value vector parameter is a whole, deep copy of callers vector.

By reference is cheap; no copy. By reference allows accessing caller's vector, just like the pointer allows accessing caller's array.

You can have const reference. Then function cannot modify the caller's variable.
Hello coff33Cup,

keskiverto has a very good answer.

I take a more simple approach.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void addCustomer(vector<PainterJobContracts>& contract)  // <--- Changed.
{
    string userInput;
    // <--- Other variables you may need.

    //prompt user to enter name
    cout << "Enter you first and last name: ";  // <--- Changed.
    //read in name

    getline(cin, userInput);

    // <--- Other information needed.

    contract.emplace_back(userInput, other variables, if needed);  // <--- Changed.
}

First like a "std::string" pass the vector by reference.

Inside the function create local variable (s) for what you need for input.

On line 14 use "emplace_back(): not "push_back()".

Putting the local variables inside the ()s will 1st call the overloaded ctor of the class and construct a temporary object object of the class before it finishes with a "push_back" to the vector.

If you are just getting the name create an overloaded ctor that just takes a "std::string" for the name. The compiler will know which overloaded ctor to use based on the parameters, (quantity and type) being the difference.

Without seeing the class I am not sure what else to tell you for now.

Andy
Topic archived. No new replies allowed.