I'm trying out a small example to practice the concepts of inheritance, and polymorphism. Here is a simplified version of my code:
class Shape {
protected:
int length;
int width;
public:
virtual void setLength(int l) = 0;
virtual void setWidth(int w) = 0;
};
class Rectangle : public Shape {
public:
Rectangle(int l, int w)
: length(l), width(w)
{ }
void setWidth(int w) { width = w; }
void setLength(int l) { length = l; }
};
int main() {
Rectangle r(0,0);
}
I'm trying to run the above program. However, when I compile rectangle.cc, I get the following error
g++ -c rectangle.cc
rectangle.cc: In constructor 'Rectangle::Rectangle(int, int)':
rectangle.cc:13:5: error: class 'Rectangle' does not have any field named 'length'
rectangle.cc:13:16: error: class 'Rectangle' does not have any field named 'width'
To my understanding, in public inheritance, protected members of the base class become protected members of the derived class and should be able to e accessed like public members. Is that incorrect? Also, how would the code then need to be modified if length and width were private members of the base class?
To my understanding, in public inheritance, protected members of the base class become protected members of the derived class and should be able to e accessed like public members. Is that incorrect?
This is mostly true. Public and protected members of base classes are accessible in derived classes (public
inheritance doesn't matter here - that only affects outside observers' access). However, class members (of any access) can only be initialized in their own class. In this case, only Shape
can initialize length
and width
- it doesn't matter that they're protected
, the same would be true if they were public
or private
.
You would have to add a constructor to do this, which your Rectangle
constructor could simply delegate to. This works regardless of the access control of length
and width
(as long as the Shape
constructor is public
or protected
):
struct Shape {
Shape(int l, int w) : length(l), width(w) { }
};
struct Rectangle {
Rectangle(int l, int w) : Shape(l, w) { }
};
Or, for completeness, you could just assign them, but definitely prefer to have Shape
initialize them. Additionally, this only works if the members in question are public
or protected
:
Rectangle(int l, int w) {
length = l;
width = w;
}
Note that your setWidth()
and setLength()
functions are fine - you do have access to those protected members in Rectangle
's member functions. Just not for initialization.
No, protected members of the base class do not become protected members of the derived class. Protected members of the base class are accessible by the derived class, unlike private members, and they remain protected, in the derived class's namespace (so the same thing applies to the derived class of the derived class, and so on).
But protected members of the base class are still members of the base class, and the base class's constructor is still responsible for constructing them, not the derived class's constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With