Base constructors and protected

Lets go back to the geometry example:

Remember Polygon and Rectangle:

class Polygon {
private:
  vector<Location *> points;
public:
  Polygon(vector<Location *> points);
  virtual void draw();
  virtual float getArea();
};
class Rectangle : public Polygon {
public:
  Rectangle(Location *topLeft, Location *bottomRight);
  virtual float getArea();
};

With the knowledge we have so far we would implement the polygon constructor as follows:

Polygon::Polygon(vector<Location *> points)
{
  this->points = points;
}

And something like this for the rectangle:

Rectangle::Rectangle(Location *topLeft, Location *bottomRight)
{
  points.push_back(topLeft);
  points.push_back(new Location(topLeft->getX(),bottomRight->getY()));
  points.push_back(bottomRight);
  points.push_back(new Location(bottomRight->getX(),topLeft->getY()));
}

Unfortunately C++ gives us strange compiler errors:

  • std::vector<Location*, std::allocator<Location*> > Polygon::points' is private

  • error: no matching function for call to `Polygon::Polygon()

What is happening here?

Answer (to the first one): points is private. Everything that is private can only be used in this particular class, and none of its superclasses. There are two options:

  • Add getters / setters and use those instead

  • change the visibility from "private" to "protected"

protected

protected methods and variables are available to all members of this class and all of its subclasses.

Answer (to the second one): Every constructor implicity calls the constructor of its superclass(es). If we don't tell it which constructor to use it tries to call the default constructor.

Unfortunately it calls the superconstructor BEFORE we can do anything.

We have therefore two choices:

  • Call a specific superconstructor

  • add a default superconstructor

In this case I decided on the default superconstructor. Here is the complete new definition:

class Polygon {
private:
protected:
  vector<Location *> points;
  Polygon() {};
public:
  Polygon(vector<Location *> points);
  virtual void draw();
  virtual float getArea();
};
  • We made "points" protected so that subclasses can use it directly

  • We added a default constructor that doesn't do anything

  • The default constructor is protected. The subclasses should be able to call it, but no one from the outside!

So the notes for inheritance in C++ are:

  • make all functions virtual

  • maybe add a default constructor

  • change some items from "private" to "protected" to give subclasses access.