If you do not explicitly tell the compiler which way to construct an object in the constructors initialiser list, the compiler will attempt to use the default constructor. This is the meaning of "no matching function for call to `cArmor::cArmor()'".
The compiler lists the constructors that are available for use, the copy constructor "cArmor::cArmor(const cArmor&)", and the one you have defined "cArmor::cArmor(int, int, int)".
To tell the compiler to use the copy constructor we will use the initialiser list. We should do this for all variables. In between the name of the constructor "className()" and the opening bracket "{", place a colon to begin the initaliser list. After that, list the members you wish to initialise in the order they are declared in the class, with commas in between. Here is your example:
cPlayer::cPlayer(string name, cArmor armor): itsHealth(100), itsEnergy(100), itsMaxHealth(100), itsMaxEnergy(100), itsMoney(5000), itsName(name), itsArmor(armor) // invoke copy ctor{ // we no longer have to do anything here}
This is equivalent to the following:
std::string str = "Hello";
std::string str("Hello");
That uses the appropriate constructor.
The way you were doing it was like this:
std::string str;
str = "Hello";
Which uses operator=(). This can be inefficient, for a class like std::vector which allocates memory in the constructor and may then have to reallocate when you invoke operator=(). It can be impossible, as in your case, when there is no default constructor defined.
[edit: thanks Zahlman!]
[Edited by - rip-off on May 11, 2007 3:12:39 PM]