views:

68

answers:

2

I have a vector called players and a class called Player. And what I'm trying to do is to write:

players.push_back(Player(name, Weapon(bullets)));

So I want to be able to create players in a loop. But I see an error message says "no matching function for call Player::Player..."

Then I've changed that to:

Weapon w(bullets);
Player p(name, w);
players.push_back(p);

Here is my Player definition:

class Player {
public:
   Player(string &name, Weapon &weapon);
private
   string name;
   Weapon weapon;
}

I'm just trying to learn what is the difference between these definitions. And is this the right way to pass an object to an object constructor.

Note: These are not my actual class definitions. I'm just trying to learn something about object oriented programming in C++ with coding it. I mean I know that Weapon can be initialized in Player :)

+4  A: 

Change constructor to:

Player(const string &name, const Weapon &weapon);

or:

Player(const string &name, Weapon weapon);

It's not valid C++ to initialize a reference with a temporary object, which is what you're doing when you use:

Player(name, Weapon(bullets));

it's legal to use a const reference though.

EDIT: You should also pass name as a const reference or by value.

Andreas Brinck
The name should also be const (it is being copied and not modified inside the constructor)
David Rodríguez - dribeas
@David You're absolutely right.
Andreas Brinck
@Andreas: Btw, Is there any difference between these two code above? I'm talking about the performance. Both of them are creating a local variable and pass right?
pocoa
@pocoa The first one passes the argument `weapon` by reference, which is essentially a pointer. The second one passes the argument by value which means that a copy of `weapon` is passed to the constructor. If the size of the class `Weapon` is larger than the size of a pointer it's usually faster to pass by reference.
Andreas Brinck
@Andreas: Sorry for my poor explanation. I was talking about my code. First one is players.push_back(Player(name, Weapon(bullets))) and the other one is 3 lines which creates Weapon and assign to Player and then adds Player to the vector. Are they same? Thank you for your time.
pocoa
@pocoa: if we pretend for a moment that your faulty code compiles and does the obvious thing, which is to take a non-const reference to the temporary object, then yes it's probably the same as your code that works. Temporary objects don't differ much from automatic variables in actual behaviour, they're just created and destroyed in secret by the compiler. In theory a compiler could do special things with them to take advantage of the fact they can only be passed by const reference, but in practice not so much. You can call a non-const member fn on a temporary: they aren't "really const".
Steve Jessop
Thank you Steve.
pocoa
+1  A: 

You are passing a temporary (Weapon(bullets)) to the Player constructor, which takes a Weapon &. But since you're not allowed to make a reference to a temporary, this fails.

You are, however, allowed to make a const reference to a temporary. Thus, redeclare your constructor as follows:

   Player(string const &name, Weapon const &weapon);
Thomas