2

I'm having a problem with some code in Visual C++ 2010 Express. I'm trying to make a class that has a constructor that accepts an argument which has a default value. Here's a short program that shows what I'm trying to achieve:

//Class declaration
class Class {
private:
    int mValue;
public:
    Class(int);
    int GetValue();
};

Class::Class(int val=1) : mValue(val)
{
}

int Class::GetValue()
{
    return mValue;
}

int main()
{
    Class test;
    cout << test.GetValue() << endl;
}

Now this seems to work fine. If I replace Class test with Class test(10), say, mValue is initialised correctly.

However, in a second program I'm trying to do exactly the same thing. I have a class defined like this:

namespace mobs {
    Class Monster {
    private:
        mHitPoints;
    public:
        Monster(int);
        int GetHitPoints() const;
    };
}

with the implementation of the functions like this:

namespace mobs {

    Monster::Monster(int hp=10) : mHitPoints(hp)
    {
    }

    int Monster::GetHitPoints() const
    {
        return mHitPoints;
    }
}

but when I try to declare a class and use the GetHitPoints() function like so:

mobs::Monster testmonster;
cout << testmonster.GetHitPoints() << endl;

Visual C++ tells me that "no default constructor exists for class mobs::Monster". Why is this?

Wheels2050
  • 879
  • 2
  • 9
  • 17
  • 1
    http://stackoverflow.com/questions/1440222/constructors-with-default-parameters-in-header-files – Mat Jul 08 '12 at 19:57

2 Answers2

5

The default value belongs in the declaration, not the definition. Move the =10 to your header file:

Monster(int hp = 10).

In the implementation, you don't even need the default value. I usually use:

Monster::Monster(int hp /*=10*/)

just to make it clear there's a default.

Eran
  • 21,632
  • 6
  • 56
  • 89
  • Excellent, thanks very much! All the examples I had seen of this defined the whole class in a single file, so I didn't know what the prototype should look like. – Wheels2050 Jul 08 '12 at 20:00
-1

The constructor is ambigious. that's why. if you have two constructors

Monster(){}
Monster(x=10){}

and you make a call Monster m();

How should the compiler know whether you mean the first or second constructor Instead Define it as follows

class Class {
private:
    int mValue;
public:
    Class(int val) :mValue(val){}
    Class() :mValue(1){}
};
Moataz Elmasry
  • 2,509
  • 4
  • 27
  • 37