Reputation: 487
I need help with an issue. I have been reminding myself how to use C++ and got back to inheritance. I have been using the tutorials on cplusplus.com for the code below
class Shape
{
protected:
int width, height;
public:
Shape(int w, int h) : width(w), height(h) { }
Shape()
{
width = 1;
height = 1;
}
void set_values (int w, int h)
{
width = w;
height = h;
}
};
class Rectangle : public Shape
{
public:
Rectangle()
{
width = 1;
height = 1;
}
Rectangle(int w, int h) : width(w), height(h) { }
~Rectangle() { }
int area ()
{
return (width * height);
}
};
However whenever I run a test, it always fails on the Rectangle's constructor. That seems to be where it always fails. Can anyone see where I have gone wrong?
Upvotes: 0
Views: 153
Reputation: 227400
You can't directly initialize base class data members in a derived class constructor, because these data members are already initialized by the base class. You need to explicitly call the base class constructor:
Rectangle(int w, int h) : Shape(w, h) { }
You can also simplify Rectangle()
. There is no need to assign values of 1
to data members that have already been initialized to that value:
Rectangle() : Shape() {}
or
Rectangle() {} // Shape() implicitly called
or, in C++11,
Rectangle() = default;
Alternatively, in C++11, you can say
class Rectangle : public Shape
{
public:
using Shape::Shape; // "inherit" shape's constructors
};
Upvotes: 3
Reputation: 683
You cannot use the super class members in sub-class constructor initialization list.
Following code will work:
class Rectangle : public Shape
{
public:
Rectangle()
{
width = 1;
height = 1;
}
Rectangle(int w, int h)
: Shape(w,h) { }
...
};
Upvotes: 0
Reputation: 55395
Rectangle(int w, int h) : width(w), height(h) { }
width and shape are members of the base class, Shape
. You can't initialize them in a derived class' constructor because the base class' constructor takes care of that.
The reason this constructor works
Rectangle()
{
width = 1;
height = 1;
}
is because that's assignment, not initialization.
Remember, before the constructor of the most derived class runs, the constructors of all base classes will be run.
You can do explicitly say which constructor of a base class you want to call by saying:
Rectangle(int w, int h) : Shape(w, h) { }
or, if the default constructor would be sufficient, just don't do anything (the compiler will call it automaticaly, then).
Upvotes: 1