Jump to content
  • Advertisement
Sign in to follow this  
Aluthreney

Question on C++ Class Inheritance

This topic is 2605 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm writting a program using simple classes and basic inheritance. I created a square class and then created a rectangle class the inherits the properties of the square class. The thing is that when I try to manipulate a private variable from the square class in a rectangle function it gives me an error. Can anyone explain why?

Code:
#include <iostream>
using namespace std;

class Square
{
private:
int x;

public:
void setValue(int n){x=n;}
void getPerimeter(){cout << "Perimeter: " << x*4 << endl;}
void getArea(){cout << "Area: " << x*x << endl;}
};

class Rectangle:public Square
{
private:
int y;

public:
void setValue(int n0, int n1)
{
x=n0;
y=n1;
}

void getPerimeter(){cout << "Perimeter: " << (x*2)+(y*2) << endl;}
void getArea(){cout << "Area: " << x*y << endl;}
};

void Squa(int i)
{
Square sq;
sq.setValue(int i);
sq.getPerimeter();
sq.getArea();
}

void Rect(int i0, int i1)
{
Rectangle rect;
rect.setValue(a, b);
rect.getPerimeter();
rect.getArea();
}

int main()
{

}

Share this post


Link to post
Share on other sites
Advertisement
Sure. Private means only class itself can access the variables/methods. What you want is protected instead of private, this will hinder access from outside but allow access from inherited classes.

Share this post


Link to post
Share on other sites
A typical solution to this problem would be to expose the value of the member through a protected accessor function, rather than making the variable protected. If there are no invariants, then protected access to the member itself might be justified. Using functions can reduce coupling.

Many would question the inheritance hierarchy here, a rectangle is clearly not a square. Your code allows for some fairly serious violations of the Liskov substitution principle. If your types were immutable, you could use inheritance to model a square as a kind of rectangle. Alternatively, you could use composition.

You also have mistakes in your functions. In the Squa function. The call to setValue() should pass just "i", it should not use the int keyword. In the Rect, you take two parameters "i0" and "i1", but you pass two undeclared values "a" and "b" to setValue().

In both cases, the arguments could have more descriptive names. For "Rect", the parameters could be called "width" and "height". For "Squa", the parameter could be called "size".

Share this post


Link to post
Share on other sites
Generally, this code:
class Rectangle : public Square

Can be read aloud as:
All Rectangles are Squares.

Given that this is obviously not true, your inheritance model is probably going to lead you to trouble. Definitely listen to rip-off.

Share this post


Link to post
Share on other sites
Thank you for you replies and thank you for your pdf. I've saved it in my desktop and I'll read as soon as I have some spare time!

Share this post


Link to post
Share on other sites
I've updated my code according to the suggestions.
#include <iostream>
using namespace std;

class Rectangle
{
private:
int width, height;

public:
void setValue(int x, int y)
{
width=x;
height=y;
}

void getPerimeter(){cout << "Perimeter: " << (width*2)+(height*2) << endl;}
void getArea(){cout << "Area: " << width*height << endl;}
};

void Rect(int x, int y)
{
Rectangle rect;
rect.setValue(x, y);
rect.getPerimeter();
rect.getArea();
}

int main()
{
int x, y;

cout << "What is the width and height of your rectangle?" << endl;
cin >> x >> y;
Rect(x, y);
}

I figured that since every square is a type of rectangle, theres no reason to create a Square class...

Share this post


Link to post
Share on other sites
Because all squares are rectangles, you could make a square class that subclasses your Rectangle class like so:


class Square : public Rectangle
{
public:
Square(int d) : Rectangle(d, d) { }
};

Share this post


Link to post
Share on other sites

Because all squares are rectangles, you could make a square class that subclasses your Rectangle class like so:

That may be reasonable for non-mutable square and rectangle classes, but if you have a mutable type, then you've got LSP issues with this kind of inheritance. This is even one of the examples mentioned in the article rip-off linked.

Share this post


Link to post
Share on other sites
@jonbonazza Mutability invalidates that assumption, even though mathematical squares are rectangles. Read the linked article for more information.

@Aluthreney That is a wonderfully data driven approach. Don't forget you can write a helper function, to simplify the case where you want to create squares.

class Rectangle { /* ... */ };

Rectangle make_square(int size)
{
Rectangle rectangle;
rectangle.setValue(size, size);
return rectangle;
}

Note that it would be nice if you provided a constructor to zero initialise the members, or perhaps don't provide a default constructor and instead force client code to specify a rectangle's initial size during construction.

You generally don't want to encourage a design where variables are uninitialised until explicitly set, because that way lies lots of bugs.

Share this post


Link to post
Share on other sites
I was going to mention that the mutator methods should probably be virtual and re-implemented in the Square class, and the that the constructor should be altered slightly, but I figured this was a given after the above posts. I was just clarifying for the OP that you COULD still subclass them if you did it carefully, because from his last example, he seemed to want to make them separate.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!