How to declare the area and volume function [closed] - c++

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 3 years ago.
Improve this question
#include <iostream>
using namespace std;
class Shape {
protected:
int _w, _h;
public:
Shape(int w, int h) : _w(w), _h(h) { }
//declaration of area and volume function
};
class Rectangle : public Shape {
public:
Rectangle(int w, int h) : Shape(w, h) { }
};
class Cube : public Shape {
public:
int _b;
public:
Cube(int w, int h, int b) : Shape(w, h), _b(b) { }
int area() { return 2 * (_w * _h + _w * _b + _b * _h); }
int volume() { return _w * _h * _b; }
};
int main() {
Shape *pt;
int w, h, b, v;
cin >> w >> h >> b;
pt = new Rectangle(w, h);
cout << pt->area() << " ";
if ((v = pt->volume()) == -1)
cout << "Undefined ";
else
cout << v << " ";
pt = new Cube(w, h, b);
cout << pt->area() << " ";
if ((v = pt->volume()) == -1)
cout << "Undefined ";
else
cout << v << " ";
}
for the input 4 5 8 the output will be 20 Undefined 184 160 and in another test case the input is 10 20 10 and the output is
200 Undefined 1000 2000 how to declare and define area() and volume() to satisfy the given test cases.

Welcome to SO.
I believe what you are looking for is how to declare the two functions for your two inherited classes, Rectangle and Cube.
The general topic that you can look into is called 'polymorphism', where the parent class can take many forms through its derived classes.
Here is an example of what you might be inclined to do, but won't work as intended:
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;
}
int volume() {
cout << "Parent class volume:" <<endl;
return 0;
}
};
What will happen if you run the code above is the parent's area and volume functions may run in ill-defined cases instead. This is because the program will try to do static linking on the functions, basically gluing them in place and preventing us from changing them.
We want to be able to change the area and volume functions to match our derived class, so what you will need to do instead, is to define your area and volume functions as 'virtual' in your parent class, like so:
class Shape {
protected:
int width, height;
public:
Shape( int a = 0, int b = 0){
width = a;
height = b;
}
virtual int area() {
cout << "Parent class area :" <<endl;
return 0;
}
virtual int volume() {
cout << "Parent class volume:" <<endl;
return 0;
}
};
The virtual functions will force the derived classes, such as rectangle or cube, to provide their own functions for those base functions, by telling the program we want to let the derived classes provide the functions instead.
Please have a look at the Stack Overflow post here for more details if you have questions in the future. They have many answers that elaborate on the subject, if there is anything I have missed here.
Hope these help you understand how to handle polymorphism better.

Related

Why it keeps return 0 when I enter the Data of The Heigh & Base

class BASIC_SHAPE (abstract)
class BASIC_SHAPE
{
public:
double GET_AREA(double _AREA) { AREA = _AREA; return AREA; }
virtual double CALC_AREA() = 0;
private:
double AREA =0;
};
Class CIRCLE
class CIRCLE:public BASIC_SHAPE
{
public:
CIRCLE() { RADIUS = 0; }
CIRCLE(double _RADIUS) { RADIUS = _RADIUS; }
virtual double CALC_AREA() {
double TEMP2 = 3.14 * pow(RADIUS, 2);
return GET_AREA(TEMP2);
}
private:
double RADIUS;
};
Class TRIANGLE
class TRIANGLE: BASIC_SHAPE
{
public:
TRIANGLE() { BASE = 0; HEIGHT = 0; }
TRIANGLE(double _BASE , double _HEIGHT) : BASE{_BASE}, HEIGHT{_HEIGHT} {}
virtual double CALC_AREA() {
double TEMP = 1 / 2 * (BASE * HEIGHT);
return GET_AREA(TEMP);
}
private:
double BASE, HEIGHT;
MAIN
CIRCLE SHAPE2;
TRIANGLE SHAPE3;
void main()
{
double RAD;
std::cout << "Enter a Circle Radius : ";
std::cin >> RAD;
CIRCLE SHAPE2(RAD);
CIRCLE* LEAD1 = new CIRCLE(RAD);
std::cout << "The Area is : " << LEAD1->CALC_AREA();
double BASE , HEIGHT;
std::cout << "\n\nEnter a Triangle Base : ";
std::cin >> BASE;
std::cout << "\nEnter a Triangle Height : ";
std::cin >> HEIGHT;
TRIANGLE SHAPE3(BASE, HEIGHT);
std::cout << SHAPE3.CALC_AREA();
}
it keeps returning zero when I input the BASE & HEIGHT
I have tried using arrow operator and get it with pointers put nothing worked , I,ve tried use pointers and other methods to give me the answer or the SUM of area but nothing happens . constructors or abstract Class are suspected but IDK how ??
As pointed out in the comments by #rturrado 1/2 is 0. 0 times anything is 0. either use 0.5 or 1/2.0*....
Also, why does your GET_AREA method set the area for the base class and return the set area? You need to have different getters and setters. Getter methods should not set and similarly setter methods should not get.
Also, it would be best if you get in the habit of using managed pointers.

Error when using super-class objects in an array made for the sub-class of that super-class [duplicate]

This question already has answers here:
What is object slicing?
(18 answers)
Closed 5 years ago.
Hey guys here is some code I am going to run, issue is it doesn't work the way I intend to. I am unable to figure out what's wrong with it. I am c++ noob please help.
#include <iostream>
#include <cmath>
#include <stdexcept>
using namespace std;
/**
* Super class
*/
class Shape
{
protected:
int _dimensions;
public:
Shape() : _dimensions{0}
{};
Shape(int dims) : _dimensions{dims}
{};
virtual double getArea() {};
// Because some shapes have no volume.
virtual double getVolume() {};
void setDimensions(int dim)
{
this->_dimensions = dim;
};
int getDimensions()
{
return this->_dimensions;
};
};
/**
* Extended classes
*/
class TwoDimensionalShape : public Shape
{
public:
TwoDimensionalShape() : Shape{2}
{};
// This should throw an error
double getVolume() {
throw logic_error("This shape ain't got area!");
};
};
class ThreeDimensionalShape : public Shape
{
public:
ThreeDimensionalShape() : Shape{3} {};
};
/**
* Final Concrete classes extending extended classes
*/
class Circle : public TwoDimensionalShape
{
protected:
double _radius;
public:
Circle(double r) : _radius{r}
{};
double getArea()
{
// pi*r^2
return M_PI * pow(_radius, 2);
}
};
class Square : public TwoDimensionalShape
{
protected:
double _side;
public:
Square(double s) : _side{s}
{}
double getArea()
{
// s^2
return pow(_side, 2);
}
};
class Triangle : public TwoDimensionalShape
{
protected:
double _base, _height;
public:
Triangle(double b, double h) : _base{b}, _height{h}
{};
double getArea()
{
// b*h/2
return _base * _height / 2;
}
};
class Sphere : public ThreeDimensionalShape
{
protected:
double _radius;
public:
Sphere(double r) : _radius{r}
{}
double getArea()
{
cout << 4 * M_PI * pow(_radius, 2) << endl;
return 4 * M_PI * pow(_radius, 2);
}
double getVolume()
{
return (4/3) * M_PI * pow(_radius, 3);
}
};
class Cube : public ThreeDimensionalShape
{
protected:
double _side;
public:
Cube(double s) : _side{s}
{};
double getArea()
{
// surface area = 6*a^2
return 6 * pow(_side, 2);
}
double getVolume()
{
// a^3
return pow(_side, 3);
}
};
class Tetrahedron : public ThreeDimensionalShape
{
protected:
double _side;
public:
Tetrahedron(double s) : _side{s}
{};
double getArea()
{
// sqrt(3)*a^2
return sqrt(3) * pow(_side, 2);
}
double getVolume()
{
// a^3/6sqrt(2)
return pow(_side, 3) / (6 * sqrt(2));
}
};
int main()
{
Shape arr[2];
arr[0] = Circle{10};
arr[1] = Sphere{10};
// This one is accessing the right method.
cout << "Area of circle: " << arr[0].getArea() << endl;
// This one should access the parent, but accesses the grand parent!
// even if it is overridden in parent.
cout << "Volume of circle: " << arr[0].getVolume() << endl;
// Both of these are accessing methods on grand parent rather than their own!!
cout << "Area of sphere: " << arr[1].getArea() << endl;
cout << "Volume of sphere: " << arr[1].getVolume() << endl;
return 0;
}
I don't know why the array methods keep accessing the grand parent functions in the last three lines, but the right method on the first.
You are experiencing Object Slicing. The portion of your code below does that:
Shape arr[2];
arr[0] = Circle{10};
arr[1] = Sphere{10};
Each of the assignments above invokes the copy assignment operator of Shape and slices off objects of the subclass. You can achieve your intention by using references or pointers:
std::unique_ptr<Shape> arr[2];
arr[0] = std::make_unique<Circle>(10);
arr[1] = std::make_unique<Sphere>(10);
This is a case of object slicing. You need to put your objects as pointers, preferably as std::unique_ptr<> into your array - or again preferably a std::vector<>
Try this:
#include <memory>
#include <vector>
// ...
int main()
{
std::vector<std::unique_ptr<Shape>> vec(2);
vec[0] = std::make_unique<Circle>(10);
vec[1] = std::make_unique<Sphere>(10);
// This one is accessing the right method.
cout << "Area of circle: " << vec[0]->getArea() << endl;
// This one should access the parent, but accesses the grand parent!
// even if it is overridden in parent.
cout << "Volume of circle: " << vec[0]->getVolume() << endl;
// Both of these are accessing methods on grand parent rather than their own!!
cout << "Area of sphere: " << vec[1]->getArea() << endl;
cout << "Volume of sphere: " << vec[1]->getVolume() << endl;
return 0;
}

How to use protected type inheritance in class?

#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.
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.

Pointer to different components of a class

I have an assignment from school to create pointers to different components of a class.
I don't understand how it works. Can someone help me with a simple program?
I have made the basic layout of what's needed. I don't know how to go about creating pointers.
#include <iostream>
#include <math.h>
using namespace std;
class Rectangle
{
int a,b;
public:
};
class Perimeter : public Rectangle
{
public:
int c;
void P(int a, int b)
{
c = 2 * (a + b);
cout << "This Is The Perimeter Of The Rectangle: " << c << endl;
}
};
class Area : public Rectangle
{
public:
int c;
void A(int a, int b)
{
c = a * b;
cout << "This Is The Area Of The Rectangle: " << c << endl;
}
};
class Diagonal : public Rectangle
{
public:
float c;
void D(int a, int b)
{
c = sqrt((a*a)+(b*b));
cout << "This Is The Diagonal Of Rectangle: " << c << endl;
}
};
#include<iostream>
#include<math.h>
using namespace std;
class Rectangle
{
int a,b;
public:
};
class Perimeter : public Rectangle
{
public:
int c;
void P(int a, int b)
{
c = 2 * (a + b);
cout<<"This Is The Perimeter Of The Rectangle: "<<c<<endl;
}
};
class Area : public Rectangle
{
public:
int c;
void A(int a, int b)
{
c = a * b;
cout<<"This Is The Area Of The Rectangle: "<<c<<endl;
}
};
class Diagonal : public Rectangle
{
public:
float c;
void D(int a, int b)
{
c = sqrt((a*a)+(b*b));
cout<<"This Is The Diagonal Of Rectangle: "<<c<<endl;
}
};
int main()
{
int e,f;
cout<<"Enter Length And Breadth: "<<endl;
cin>>e>>f;
/***************************************/
Perimeter p; //CREATING AN OBJECT
Perimeter *Peri; //CREATING A POINTER TO THE OBJECT
Peri=&p; //ASSIGNING ADDRESS TO THE POINTER
Peri->P(e,f); //MEMBER ACCESS USING POINTER TO AN OBJECT
/**************************************/
Area a;
int Area::*ptr=&Area::c; //CREATING A POINTER TO THE DATA MEMBER
a.*ptr = e;
a.A(e,f);
/*************************************/
Diagonal d;
void (Diagonal::*Dia)(int,int)=&Diagonal::D; //CREATING POINTER TO MEMBER FUNCTION
(d.*Dia)(e,f); //THIS IS HOW WE CALL THE MEMBER FUNCTION USING ITS POINTER
/*************************************/
return 0;
}
I believe this is what you were looking for.
there are some errors you made in the program. i didn't correct them but i am pointing them out.
though you didn't write anything(create any functions) in the parent class, creating pointer to an object of the sub-class is useless. in this case, early binding is taking place. you can go with a pure virtual function following function Over-Riding.
A pointer is a reference to an area in memory.
In the picture, foo is holds the value 1702 which is the spot in memory the string "hello" is stored. Pointers to elements in a class work the same way. Your class will occupy some part of memory and a pointer to the class member will hold the value of where the class member is in memory.
I'm not sure which type of pointer you're supposed to use for your class, but there's three different types.
Raw pointers:
These are the types similar to shown in the picture. An example would be:
int * x = 5; // Let's say 5 is stored at memory location 0x15
cout << x; // This will give 0x15
cout << *x; // This "dereferences" the pointer also known as go to that memory location and retrieve the value. This outputs 5
There are also Smart Pointers as defined here:
https://learn.microsoft.com/en-us/cpp/cpp/smart-pointers-modern-cpp?view=vs-2019
These are meant to be safer since they will be garbage collected, and prevent common dereferencing errors.
For using pointers in a class it could be as easy as:
class shape {
int * height;
int * width;
public:
void setHeight (int x) {height = &x; }
void setWidth(int x) { width = &x; }
int getHeight(){ return *height; }
int getWidth() { return *width; }
};
class square : class shape {
public getArea(int *h, int *w) {returns *h * *w; }
};
int main {
int x = 5;
int y = 6;
int * pointerX = &x; //& means this variable's memory address
int * pointerY = &y;
rect rectangle;
std::cout << rectangle.getArea(pointerX, pointerY) << std::endl;
rectangle.setHeight(7);
std::cout << "Rect height:" << rectangle.getHeight() << std::endl;
rectangle.setWidth(9);
std::cout << "Rect width:" << rectangle.getWidth() << std::endl;
rect * ptrRect = &rectangle;
std::cout << ptrRect->getArea(pointerX, pointerY) << std::endl;
ptrRect->setHeight(9);
std::cout << "ptrRect height:" << ptrRect->getHeight() << std::endl;
ptrRect->setWidth(10);
std::cout << "ptrRect width:" << ptrRect->getWidth() << std::endl;
std::cout << square.getArea(pointerX, pointerY) << std::endl;
}

Runtime error in a class using virtual void functions but no compilation error

This is my code:
/*
create an abstract class shape and derived classes rectangle and circle from class shape, implement abstract method of class shape in rectangle and circle. Class circle contains radius as data members rectangle class contains length and breadth.
*/
class shape
{
virtual void displayArea() = 0;
virtual void get_radius(double r) = 0;
virtual void get_length(double a) = 0;
virtual void get_breadth(double b) = 0;
};
class rectangle: public shape
{
protected:
double length;
double breadth;
public:
virtual void get_length(double a)
{
length = a;
}
virtual void get_breadth(double b)
{
breadth = b;
}
virtual void get_radius(double r)
{
cout << endl;
}
virtual void displayArea()
{
cout << "Area of RECTANGLE = " << length*breadth << endl;
}
};
class circle: public shape
{
protected:
double radius;
public:
virtual void get_length(double a)
{
cout << endl;
}
virtual void get_breadth(double b)
{
cout << endl;
}
virtual void get_radius(double r)
{
radius = r;
}
virtual void displayArea()
{
cout << "Area of circle = " << 3.14*radius*radius << endl;
}
};
int main()
{
shape* shapes;
double l, r, b;
rectangle R;
circle C;
cout << "Enter the length and breadth for rectangle\n" << endl;
cin >> l >> b;
cout << "\nEnter the radius of circle\n " << endl;
cin >> r;
R.get_length(l);
R.get_breadth(b);
C.get_radius(r);
shapes[0] = R;
shapes[1] = C;
shapes[0].displayArea();
shapes[1].displayArea();
system("pause");
return 0;
}
It is giving no compilation errors but during runtime this happens:
Enter the length and breadth for rectangle
3
3
Enter the radius of circle
3
Then it pauses for sometime and then terminates. I am confused, what have I done wrong here and how to correct it? And what issues are there with the code?
Your shapes variable is uninitialized (which I suppose it to be array) , you need to initialize it with the address of objects :
shape* shapes[2] ;
//...
shapes[0] = &R;
shapes[1] = &C;
shapes[0]->displayArea();
shapes[1]->displayArea();
For a start you have no constructors or setter functions (at least you have not shown any code for them) so there is no way to set your class member variables.
Secondly you cant do this
shape* shapes;
shapes[0] = R;
shapes[1] = C;
as shapes is a pointer for which you have not allocated memory. If you want an array of shape pointers you must declare shapes as an array and if it is an array of pointers, you should assign pointers to its elements and not objects.
EDIT I see that in fact you do have setter functions, and that you have called them get_length() get_radius() etc. This is highly confusing and you would be better using variable names that indicate what they do where possible. To someone reading your code this is very confusing
The line
shape* shapes;
declares a pointer to a shape object. However, you have not allocated any memory for any shapes. Then you later use this pointer as an array:
shapes[0] = R;
shapes[1] = C;
This causes undefined behavior since this memory location is not allocated for use by your program.
One thing that I noticed about your code is that 'shapes' is not actually an array. It is a non-initialized pointer. So shapes[0]=R will not point member#0 to R, it will copy it to wherever the pointer points to. The next line will do something similar. This will probably cause memory corruption. You probably want something like
shape* Shapes[2];
Or even (moving this line to after the place C and R are declared):
shape** Shapes = {
&R,
&C
};