1

Learning C++ and getting error "no matching function for call to 'Weapon::Weapon(int, const char [4], int, int)'" when creating a weapon istance

Weapon MyWeapon(1,"test",4,1);

Where is the bug?

item.h

#ifndef ITEM_H
#define ITEM_H
#include <string>
#include <iostream>

using namespace std;
class Item
{
public:
  string name;
  int weight;
  int value;
  Item(string n, int w, int v);

};
#endif

item.cpp

#include <iostream>
#include <string>
#include <vector>
#include "item.h"
using namespace std;
Item::Item(string name, int weight, int value)
{
    name=name;
    weight=weight;
    name=value;
}

weapon.h

#ifndef WEAPON_H
#define WEAPON_H
#include "item.h"
class Weapon : public Item
{
public:
  int damage;
  Weapon();
  Weapon(int damage);
};

#endif

weapon.cpp

#include <iostream>
#include <string>
#include <vector>
#include "weapon.h"
using namespace std;
Weapon::Weapon( damage): Item(name, weight, value){}
  • 3
    What is `name`, `weight` and `value` in `Weapon::Weapon( damage): Item(name, weight, value){}`? It looks to me like it's meant to refer to the uninitialized members. In other words, what is the `Weapon`'s `name`? It looks like you define `name` to be initialized to itself. – François Andrieux Feb 17 '20 at 18:55
  • The confusion appears to be that OP thinks class inheritence and calling a base constructor in the derived initialization list creates creates a function signature that concatenates the derived signature and the base signature. This is not the case! As answers below state, you need to explicitly accept all parameters you want to use in the `Weapon` constructor, and then they may be passed on to base constructors in the initialization list. – JohnFilleau Feb 17 '20 at 19:05
  • Also, having `name`, `weight`, and `value` as member variables of `Item` would be fine, if you weren't also using these names as parameters of the `Item::Item(string, int, int)` constructor. That constructor assigns the values of the local variables `name` and `weight` to themselves, (and in a typo, assigns the value of `value` to `name`). This is certainly unintended behavior. You can avoid this by adopting a coding style that names all member variables uniquely from function parameters, such as appending an underscore to the member variables. i.e., `name` would become `name_`. – JohnFilleau Feb 17 '20 at 19:08
  • @John thanks, appreciate. – user3024185 Feb 17 '20 at 21:27

2 Answers2

0

You're getting "no matching function for call to Weapon::Weapon(int, const char [4], int, int)" because there isn't a constructor with that signature. Change the Weapon definition to something like this:

class Weapon : public Item
{
public:
  int damage;

  Weapon(int damage, std::string name, int weight, int value);
};

Then fix up weapon.cpp to send those arguments to the Item constructor:

Weapon::Weapon(int damage, std::string name, int weight, int value) :
    Item(name, weight, value),
    damage(damage)
{ }

Also a quick side note: using namespace std is considered a bad practice.

Travis Gockel
  • 26,877
  • 14
  • 89
  • 116
0

You need to explicitly specify all the Item arguments in the Weapon constructor.

Change the header like this:

Weapon(int damage, string n, int w, int v);

And the implementation like that:

Weapon::Weapon(int damage, string n, int w, int v): damage(damage), Item(name, weight, value){}
user3684240
  • 1,420
  • 2
  • 12
  • 18