C++ Inheritance : Base attributes over various derived objects - c++

I'm currently learning about C++ Inheritance, so if this question is a dumb one, I apologize in advance.
Implementing this scenario:
A super class has a color attribute, which can be any color (let's assume color is represented by an integer).
Let's assume I have an initialization of this super class, with the color red.
I am also going to initialize different objects of a sub-class which also share the color red.
My question is, is there any way that I can initialize this attribute color to red (or any color for that matter) and it would be automatically inherited by objects of it's sub-class, instead of setting the attribute to red every-time I initialize one of these objects?
Again apologies if I'm missing a basic concept here, but I can't seem to find anything online on this.
Pseudo-Code per request:
Super-class code:
class Shape {
int color;
Shape::Shape(int c) : color(c) { } //constructor
}
Sub-Class code:
class Square {
int length, width;
Square::Square(int l, int w, int c)
: length(l),
width(w),
color(c)
{ }
}
class Circle {
int radius;
Square::Square(int r, int c)
: radius(r),
color(c)
{ }
}
What I'm trying to say is that both square and circle need to have the same color, is there anyway (maybe from the super class? ) to declare this color (ex. red), and both shapes would have this color set the same?

You could accomplish what you want with a static default_color that gets used when no color is explicitly specified, and gets set whenever a color is specified.
struct Shape {
static int default_color;
int color;
Shape(int c) : color(c)
{
default_color = c;
}
Shape() : color(default_color) {}
};
Shape::default_color = BLACK;
struct Square : public Shape {
int length, width;
Square(int l, int w, int c)
: Shape(c),
length(l),
width(w),
{ }
Square(int l, int w)
: length(l),
width(w)
{ }
}
struct Circle : public Shape {
int radius;
Circle(int r, int c)
: Shape(c),
radius(r)
{ }
Circle(int r)
: radius(r)
{ }
}
int main()
{
Square sq(2, 3, RED);
Circle cir(10); // Automatically red, since that's
the last color explicitly specified
}
I would say this is a poor design though. Global state like this makes it very easy to make mistakes. You now have to think about the state of the entire program whenever you create a shape. It would be better to simply create the Circle as Circle cir(10, sq.color);. That makes it explicit what color your Circle is, and reduces cognitive load on the programmer.

Prior to C++11, the primary way to do this would be as follows:
class baseClass
{
int color;
baseClass() { color = RED; }
};
class subClass : public baseClass
{
subclass() { }
};
With C++11 and later, you can assign the default value in the class declaration:
class baseClass
{
int color = RED;
baseClass() { }
};
This would be inherited.
EDIT: As mentioned below, the default baseClass constructor is automatically called in this case.

There's a difference between a class and an instance of a class. A class is something like a structure, according to which further instances will be created. A class is something like a description, an instruction how to build objects. Inheritance is related to classes, not to objects. As for fields, the inherited class has all the same fields from the parent class plus some new fields you may add.
A simple example for you:
class MyBase {
public:
int color;
};
class MyChild : public MyBase {
public:
double length;
}
int main() {
MyBase myBaseObj;
myBaseObj.color = 1;
MyChild myChildObj;
myChildObj.color = 2;
myChildObj.length = 3.14;
return 0;
}

is there anyway (maybe from the super class? ) to declare this color (ex. red), and both shapes would have this color set the same?
In your posted example, yes. A super-class constructor can set its variables to whatever it wants to, for example:
Shape::Shape(int c) : color(7) { } // 7 == RED
If Shape had that constructor defined, then instances of every subclass would represent red shapes.
This sample program prints 7, overriding the user's chosen color:
#include <iostream>
class Shape {
public:
int color;
Shape(int c) : color(7) { } //constructor
};
class Square : public Shape {
public:
int length, width;
Square(int l, int w, int c)
: Shape(c),
length(l),
width(w)
{ }
};
class Circle : public Shape {
public:
int radius;
Circle(int r, int c)
: Shape(c),
radius(r)
{ }
};
int main() {
Square q(4,8,0);
std::cout << q.color << "\n";
}

Related

How to call different derived classes in constructors of classes derived from a different base class

In C++, I have two separate base classes, each of whose derived classes are somewhat coupled. Here's an example for the kind of thing I'd like to do:
First define a set of classes, e.g.,:
class Shape
{
public:
double area;
double diameter;
};
class Rectangle : public Shape
{
public:
double width;
double height;
};
class Circle : public Shape
{
public:
double radius;
};
The second set of classes then pertains to operations being performed on this first set of classes, something like this:
class Calculator
{
public:
static Calculator *create_calculator(shape *shape,const char *shape_type); // the factory
virtual void calculate()=0; // the actual calculation
};
class area_circles : public Calculator
{
class circles *circle;
public
area_circles(circles *circle)
{
this->circle = circle;
}
void calculate()
{
this->area = PI*pow(circle->radius,2);
}
}
class area_rectangles : public Calculator
{
class rectangles *rectangle;
public
area_rectangles(rectangles *rectangle)
{
this->rectangle = rectangle;
}
double calculate()
{
this->area = rectangle->height * rectangle->width;
}
}
Calculator *Calculator::create_calculator(shape *shape, const char *shape_type)
{
if (shape_type=="circle")
return new area_circles(shape);
if (shape_type=="rectangle")
return new area_rectangles(shape);
}
Then, the idea would be to call all this using something like:
rectangles *my_rectangle;
Calculator *area_calculator;
area_calculator = area_calculator->create_calculator(my_rectangle, "rectangle");
area_calculator->calculate();
However, this doesn't compile and I get an error (quite sensibly) pointing out how the Shape class has no member "width", and that "a value of type "shape *" cannot be assigned an entity of type "rectangles". The error's pretty clear on why this code isn't working.
Would anyone know how to get the code here to do what I'm trying to do?
From a design perspective, I recognize that part of the problem is that the derived classes end up being coupled, so maybe there is a better way to try to decouple the calculator class from the shape class. But I'd like to at least try out this approach for a while as well in my implementation, and for that I need the code to compile.
I am not entirely sure what you are trying to achieve here but I think the more usual approach to it is something like this:
class Shape
{
public:
virtual ~Shape() {}
// concrete classes must implement this function
virtual double get_area() const = 0;
};
class Circle
: public Shape
{
double diameter;
public:
Circle(double diameter): diameter(diameter) {}
virtual double get_area() const
{
return M_PI * diameter * diameter / 4;
}
};
class Rectangle
: public Shape
{
double width;
double height;
public:
Rectangle(double width, double height): width(width), height(height) {}
virtual double get_area() const
{
return width * height;
}
};
int main()
{
Circle c(2);
Rectangle r(20, 40);
// use Shape references (or pointers) to invoke polymorphic behaviour
Shape& cs = c;
Shape& rs = r;
std::cout << "Area of circle : " << cs.get_area() << '\n';
std::cout << "Area of rectangle: " << rs.get_area() << '\n';
}

Example of a pointer to class object in c++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
In the following code in main function, shape is declared as a pointer to class Shape object but the address of object of class Rectangle namely rec is saved in the following line.Can somebody please tell me where I am wrong in my understanding.
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
int area()
{
cout << "Parent class area :" <<endl;
return 0;
}
};
class Rectangle: public Shape{
public:
Rectangle( int a=0, int b=0)
{
Shape(a, b);
}
int area ()
{
return (width * height);
}
};
class Triangle: public Shape{
public:
Triangle( int a=0, int b=0)
{
Shape(a, b);
}
int area ()
{
return (width * height / 2);
}
};
int main( )
{
Shape *shape;//pointer to Shape class
Rectangle rec(10,7);
Triangle tri(10,5);
shape = &rec;//address of Rectangle class object saved
shape->area();
shape = &tri;
shape->area();
return 0;
}
Shape needs to declare area as virtual to get polymorphic behaviour.
virtual int area()
{
...
}
Your code has several errors and as the result the code has no a sense.
Consider for example constructor
Triangle( int a=0, int b=0)
{
Shape(a, b);
}
Ar first the default constructor of Shape will be called because you did not specify a call of the Shape constructor in the ctor initialization list. So width and height will be set to zero by the default constructor.
Inside the body of constructor of Triangle you simply create a temporary object of type Shape that will be used never.
It could look the dollowing way
Triangle( int a=0, int b=0) : Shape( a, b ) {}
or even as
explicit Triangle( int a=0, int b=0) : Shape( a, b ) {}
if you know what explicit means.
Apart from this the class hierarchy shall be based on virtual functions that you could get the effect of the polimorphism. So class Shape should be defined the following way
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0) : width( a ), height( b ) {}
virtual ~Shape() {}
virtual int area() const = 0;
};
int Shape::area() const
{
cout << "Parent class area :" <<endl;
return 0;
}
And uodate the derived classes according to these changes.
Rectangle is derived from Shape, see the line
class Rectangle: public Shape
This is called inheritance or an "is-a" relation: a Rectangle is a Shape. Therefore, a Shape* can point to a rectangle. More info, can, for example, be found in Base class pointer vs inherited class pointer? or most C++ tutorials covering inheritance.
As Roddy's answer notes, however, you should declare area in Shape as virtual, otherwise calling shape->area() will always call Shape's area method instead of the overridden method provided by Rectangle. Since area for Shape does not really make sense, you might even consider declaring it as pure virtual:
virtual int area() = 0;

shadows a parameter when single parameter on constructor

Hi I was coding simple class followed by sample code in web.
This code works fine without an error.
class Shape{
protected:
int width,height;
public:
Shape(int a = 0, int b=0)
{
width = a;
height = b;
}
};
class regSquare: public Shape{
public:
regSquare( int a=0, int b=0)
{
Shape(a, b);
}
};
but when I change my to have only one parameter for the constructor such as
class Shape{
protected:
int width;
public:
Shape(int a = 0)
{
width = a;
}
};
class regSquare: public Shape{
public:
regSquare(int a = 0)
{
Shape(a);
}
};
it occurring error with this massage
'error: declaration of `a' shadows a parameter'
I have no idea what is wrong about my code
Most likely neither version does what you want, though! The code
regSquare(int a = 0, int b = 0) {
Shape(a, b);
}
Does not initialize the Shape subobject of your regSquare object! Instead, it creates a temporary object of type Shape with the parameters a and b. The one parameter version does something similar:
Shape(a);
defines a default constructed object of type Shape called a. You probably meant to use the initializer list to pass the constructor arguments to the Shape subobject, e.g.:
reqSquare(int a = 0, int b = 0)
: Shape(a, b) {
}
or
regSquare(int a = 0)
: Shape(a) {
}
Because in single arguement compiler takes it as object name and creating an object so it is creating a conflict.

C++ inherit from a concrete class to another concrete class

I'm trying to inherit from one of my class 2 variables which they must be equal to be able to return the value of one of my functions in the other class..
class Rectangle: public Shape{
double Length;
double Width;
public:
Rectangle(double Length, double Width):
Shape("Rectangle")
{
this->Length=Length;
this->Width=Width;
}
double getPerimerter(){
return 2 * (Length+Width);
}
double getArea(){
return Length * Width;
}
};
class Square: public Shape, public Rectangle{
double Side;
public:
Square():
Shape("Square"),
Rectangle(Length,Width)
{}
double getPerimerter(){
if(Length==Width)
return 4 * (Length+Width);
}
double getArea(){
if(Length==Width)
return (Length+Width) * (Length+Width);
}
};
as you can see I have already a concrete class call Rectangle which hold to private variables with the names Length and Width.. What I'm trying to do is inherit this class to my class Square and if Length and Width are equal then I can return the Area and Perimeter of the Square..
It is perfectly fine to inherit from an existing class.
What you probably want, however, is this:
class Square: public Rectangle
{
public:
Square(double Side) : Rectangle(Side, Side) { }
};
That way, there is no problem of someone trying to use a ractangular square Square(4.3, 9.6).
Alternatively, you could of course use typedef Rectangle Square;
Edit:
To overcome the "name", we could do something like this:
class Rectangle
{
public:
Rectangle(double Length, double Width) : Shape("Rectangle") { ... }
protected:
Rectangle(double Length, double Width, const char *name) : Shape(name), Length(Length), Width(Width) {}
};
class Square
{
public:
Square(double side) : Rectangle(side, side, "Square") {}
};
Edit2: Code that I came up with:
#include <iostream>
using namespace std;
class Shape
{
private:
const char *name;
public:
Shape(const char *name) : name(name) {}
virtual double getPerimeter() = 0;
virtual double getArea() = 0;
};
class Rectangle: public Shape{
double Length;
double Width;
public:
Rectangle(double Length, double Width):
Shape("Rectangle")
{
this->Length=Length;
this->Width=Width;
}
double getPerimeter(){
return 2 * (Length+Width);
}
double getArea(){
return Length * Width;
}
protected:
Rectangle(double Length, double Width, const char *name):
Shape(name)
{
this->Length=Length;
this->Width=Width;
}
};
class Square: public Rectangle
{
public:
Square(double Side):
Rectangle(Side,Side, "Square")
{
}
};
int main()
{
Square sq(10.0);
Rectangle rect(12.0, 4.0);
cout << "sq:" << sq.getArea() << " rect:" << rect.getArea() << endl;
}
As a first thing you should add an argument to Square constructor, like so:
Square(double Side):Rectangle(Side,Side){
// Add additional constructor code here if required
}
About returning a value in a constructor - that is a no-go as the constructor might not return anything.
I hope this is what you meant as your question was quite hard for me to understand.
I might not understand your question, but it looks to me like you only need to add a parameter to your Square() constructor. It would look like this:
class Square: public Rectangle{
public:
Square(double dimension):
Rectangle(dimension, dimension){
}
};
There is no need for a conditional statement in the Square() constructor. Creating a Square necessarily implies creating a Rectangle with equal length and width.

Nested Classes variable calls

I want to go from this:
To this:
How would I do this? How would the functions of subclasses square and rectangle know to use the variable of the parent class shape?
How would I set length and width from main?
#include <iostream>
#include <cmath>
using namespace std;
class SHAPES
{
public:
class SQUARE
{
int perimeter(int length, int width)
{
return 4*length;
}
int area(int length, int width)
{
return length*length;
}
};
public:
class RECTANGLE
{
int perimeter(int length, int width)
{
return 2*length + 2*width;
}
int area(int length, int width)
{
return length*width;
}
};
};
I recommend other (better?!) format:
class Shape
{
protected:
int length,width;
public:
Shape(int l, int w): length(l), width(w){}
int primeter() const
{
return (length + width) * 2;
}
int area() const
{
return length * width;
}
};
class Rectangle : public Shape
{
public
Rectangle(int l, int w) : Shape(l,w){}
};
class Square : public Shape
{
public:
Square(int l): Shape(l,l){}
};
int main()
{
Rectangle r(5,4);
Square s(6);
r.area();
s.area();
}
Or use interface with virtual function.
Those are not subclasses (i.e. derived classes), but rather nested classes (as the title of your question says).
I don't think I would answer your real question if I were to tell you how to make those variables visible in nested classes. Based on what I can understand from the names of your classes, you should rather use inheritance to model the IS-A relation between them:
class SHAPE
{
public: // <-- To make the class constructor visible
SHAPE(int l, int w) : length(l), width(w) { } // <-- Class constructor
...
protected: // <-- To make sure these variables are visible to subclasses
int length;
int width;
};
class SQUARE : public SHAPE // <-- To declare public inheritance
{
public:
SQUARE(int l) : SHAPE(l, l) { } // <-- Forward arguments to base constructor
int perimeter() const // <-- I would also add the const qualifier
{
return 4 * length;
}
...
};
class RECTANGLE : public SHAPE
{
// Similarly here...
};
int main()
{
SQUARE s(5);
cout << s.perimeter();
}