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();
}
Related
I understand that you can access members of the base class from a derived class, however, I have a function that requires a pointer to my base class as a whole. For example:
#include <iostream>
using namespace std;
function foo(Shape &s){
//does something
}
// Base class
class Shape {
public:
Shape(int w = 100, int h = 100){
width = w;
height = h;
}
void setWidth(int w) {
width = w;
}
void setHeight(int h) {
height = h;
}
protected:
int width;
int height;
};
// Derived class
class Rectangle: public Shape {
public:
Rectangle(){
Shape();
}
int getArea() {
return (width * height);
}
};
int main(void) {
Rectangle Rect;
foo(// Pointer Reference to Rect.Shape here);
return 0;
}
Is there any way to get a pointer to this base class from the derived class?
Here's a working version of your code. I made some changes to it and added comments to explain the changes. Your program requires polymorphism to behave as expected, otherwise you'll 'slice' your derived object and just have a Base object.
#include <iostream>
#include <string>
// Base class
// Your base should only have things that would be common to all derived classes
// Consider what the width and height of a Circle would be
//
// You may not have gotten to virtual functions and polymorphism yet. This is
// how you would set up an interface for your Derived classes. I am requiring
// any derived class to implement getArea() and identify() if it wants to be a
// 'concrete' class. Otherwise it will be abstract, which means you can't
// declare objects of that type. It is not possible to declare a Shape object
// because of the pure virtual functions
class Shape {
public:
virtual ~Shape() = default; // A virtual destructor is required
virtual double getArea() const = 0; // Pure virtual function
virtual std::string identify() const = 0;
};
// Derived class
class Rectangle : public Shape {
public:
// The base class should be initialized in the constructor's
// initialization section. What you did was declare a temporary Shape that
// went away when the function ended.
// All class data should be set in the initialization section
Rectangle(int w, int h) : Shape(), width(w), height(h) {}
double getArea() const override { return (width * height); }
std::string identify() const override { return "Rectangle"; }
private:
int width = 0;
int height = 0;
};
// A new derived class that should work (a circle **is-a** shape), but doesn't
// with your setup. Circles don't have width and height
class Circle : public Shape {
public:
Circle(int r) : Shape(), radius(r) {}
double getArea() const override { return 2 * 3.14 * radius * radius; }
std::string identify() const override { return "Circle"; }
private:
int radius = 0;
};
// Subjective, I moved the function below the class definitions and added a body
void foo(Shape &s) {
std::cout << "A " << s.identify() << " with area " << s.getArea() << ".\n";
}
int main(void) {
Rectangle rect(5, 3);
foo(rect);
Circle circ(4);
foo(circ);
return 0;
}
Output:
A Rectangle with area 15
A Circle with area 100.48
If I remove all the virtual stuff, a lot of things stop working. I now have to provide implementations for the Shape functions. That logically doesn't make much sense. And while I can pass my derived objects to foo(), they get sliced, and the filler Shape data gets printed instead.
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
class shape
{
public:
int width;
int height;
data(int w,int h){width=w;height=h;}
};
class Rectangle: public Shape
{
public:
int area ()
{
return (width * height);
}
};
class Triangle: public Shape
{
public:
int area ()
{
return (width * height / 2);
}
};
int main()
{
Rectangle rect;
Triangle tri;
rect.data(5,3);
tri.data(10,2);
cout<<rect.area()<<endl;
cout<<tri.area()<<endl;
return 0;
}
my code did not achive the inherting part and i am gitting erorr masseage
that says
"error: expected class-name before '{' token| "
the erorr in line ( class Rectangle: public Shape )
so what can i do to solve this?
There are several errors:
The C++ is case-sensitive, shape isn't equivalent to Shape identifier. One of them must be the same as the other.
The class variables must be private, protected when the base class is to be derived. Otherwise, it violates the rule of OOP.
The datatype of data() defaults to int but nothing's returned. That's why not getting print anything. Change it to void.
Thus, the correct class code should look something like (notice comments):
class shape {
// The identifiers followed by 'protected:' will be visible to the class only
protected:
int width;
int height;
public:
// Must be 'void' since it's returning nothing and defaults to 'int'
void data(int w, int h) {
width = w, height = h;
}
};
// 'shape' != 'Shape'
class Rectangle : public shape {
public:
int area(void) {
return (width * height);
}
};
// 'shape' != 'Shape'
class Triangle : public shape
{
public:
int area(void) {
return (width * height / 2);
}
};
I have created three class: Square, Rectangle and Polygon. Square is inheriting from Rectangle and Rectangle is inheriting from Polygon.
The problem is that whenever I call Square constructor, Rectangle constructor get called and I get an error. How can I solve this?
#include <iostream>
using namespace std;
// Multilevel Inheritance
class Polygon
{
protected:
int sides;
};
class Rectangle: public Polygon
{
protected:
int length, breadth;
public:
Rectangle(int l, int b)
{
length = l;
breadth = b;
sides = 2;
}
void getDimensions()
{
cout << "Length = " << length << endl;
cout << "Breadth = " << breadth << endl;
}
};
class Square: public Rectangle
{
public:
Square(int side)
{
length = side;
breadth = length;
sides = 1;
}
};
int main(void)
{
Square s(10);
s.getDimensions();
}
If I comment out the Rectangle constructor, everything works fine. But I want to have both constructors. Is there anything I can do?
You should not set members of a base class in a derived class constructor. Instead, call the base class constructor explicitly:
class Polygon
{
protected:
int sides;
public:
Polygon(int _sides): sides(_sides) {} // constructor initializer list!
};
class Rectangle: public Polygon
{
protected:
int length, breadth;
public:
Rectangle(int l, int b) :
Polygon(2), // base class constructor
length(l),
breadth(b)
{}
};
class Square: public Rectangle
{
public:
Square(int side) : Rectangle(side, side)
{
// maybe you need to do this, but this is a sign of a bad design:
sides = 1;
}
};
constructor should be
Square(int side) : Rectangle(side, side) { sides = 1; }
as Rectangle has no default constructor.
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.
So, my problem is I don't really know a lot about classes. So, I am trying to get this constructor to work. I need the base constructor and the constructor of the derived class to work without implementing it there. I can define it there i just can't implement it. The compiler is telling me it's expecting a curly brace.
#ifdef SHAPE.H
#endif SHAPE.H
#define
#include<string>
using namespace std;
class QuizShape
{
private:
char outer, inner;
string quizLabel;
public:
//Constructor
QuizShape();
};
class Rectangle : public QuizShape
{
public:
int height, width;
//Getter & setter methods
int getHeight() const;
void setHeight(int);
int getWidth() const;
void setWidth(int);
//Constructor for Rectangle
Rectangle() : QuizShape();
};
class Square : public Rectangle
{
public:
//constructors
Square() : Rectangle (); This area here is where the error comes // IT says it expects a { but I'm not allowed to define the constructor in line.
Square(int w, int h) : Rectangle (height , width);
};
class doubleSquare : public Square
{
//Fill in with constructors
};
I don't understand the error it's giving me. I'm pretty sure I'm not redefining it either.
The constructor needs to be defined. Pls observe the changes in the way constructors are defined/used.
#include<string>
using namespace std;
class QuizShape
{
private:
char outer, inner;
string quizLabel;
public:
//Constructor
QuizShape();
};
class Rectangle : public QuizShape
{
public:
int height, width;
//Getter & setter methods
int getHeight() const;
void setHeight(int);
int getWidth() const;
void setWidth(int);
//Constructor for Rectangle
Rectangle() { }
Rectangle(int h, int w): height(h), width(w) { }
};
class Square : public Rectangle
{
public:
//constructors
Square() { } //
Square(int w, int h) : Rectangle (h, w) {}
};
class doubleSquare : public Square
{
//Fill in with constructors
};
Move your constructor initializer lists to the definitions. For example, for Square:
//declarations
Square();
Square(int w, int h);
//definitions
Square() : Rectangle() {/*body*/}
Square(int w, int h) : Rectangle(w, h) {/*body*/} //assuming you meant w, h
Do that for the other constructors with initializer lists in the declarations as well.