3
    #include<iostream>
#include<string>
#include<cmath>
using namespace std;
class Polygon {
public:
    Polygon() {}
    Polygon(int point, float length) {
        mPoint = point;
        mLength = length;
    }
    ~Polygon() {}
    virtual void calcPerimeter() {
        cout << "Perimeter: " << mLength * mPoint;
    }
    virtual void calcArea() {
        cout << "Area: " << sqrt(3) * pow(mLength, 2) / 4;
    }
protected:
    int mPoint;
    double mLength;
};

class Rectangle : public Polygon {
public:
    Rectangle() {}
    Rectangle(int point, float length):mPoint(4), mLength(4 * length){}
    ~Rectangle() {}
    void calcPerimeter() override {
        cout << "Perimeter: " << mLength;
    }
    void calcArea() override {
        cout << "Area: " << mLength * mLength;
    }

};

int main() {
    Polygon pol;
    Rectangle rec(4, 10);

    cout << "--- Polygon class---" << endl;
    pol.calcPerimeter();
    pol.calcArea();
    cout << "---Rectangle class---" << endl;
    rec.calcPerimeter();
    rec.calcArea();

    return 0;
}

I learned that if the protected part of the parent class is inherited as public, it is used like a private in the child class. By the way

Rectangle (int point, float length): mPoint (4), mLength (4 * length) {}

In this part, I get the error that mPoint and mLength are not non-static data members or the base class of Reactangle. If it's private, can't I use it like that in a class ??

If I'm misunderstanding, I hope you can tell me what's wrong. Thanks for reading.

  • 1
    You need to constuct it via `Rectangle (int point, float length) : Polygon(point,4*length) {}`. I guess this [answer](https://stackoverflow.com/a/2290803/8359552) fits perfectly to your problem. – StefanKssmr May 24 '20 at 07:50
  • Thanks! It works fine. But can you tell me what's wrong with the method I did? –  May 24 '20 at 07:54
  • 1
    See this [answer](https://stackoverflow.com/a/2290803/8359552). It descirbes everything. – StefanKssmr May 24 '20 at 07:56
  • 1
    You ilustrate why it is conceptually incorrect to have a Rectangle model inheriting a Polygon model. The mathematical objects inherit, but not their c++ counterparts. Ducktyping is a better solution. – Benjam May 24 '20 at 08:06

1 Answers1

3

You're right about being able to use protected data in the derived class. However, that's not the problem here.

In

Rectangle (int point, float length): mPoint (4), mLength (4 * length) {}

you are initializing the fields, and that can only be done once, in the initializer list of the constructor of the class in which they are declared (Polygon).

You could assign them in the body of the constructor:

Rectangle (int point, float length)
{
    mPoint = 4;
    mLength = 4 * length;
}

but better is just to call the base class constructor and let it do its job:

Rectangle (int point, float length):Polygon (4, 4 * length) {}

All of this begs the question why you're passing point to the Rectangle constructor when you don't use it.

Also, it's widely regarded as bad practice to have protected fields (protect methods are okay) because once they are protected they are accessible all the way down the inheritance hierarchy. Better to keep them private and provide protected set methods.

Jasper Kent
  • 3,546
  • 15
  • 21