My task is to practice inheritance, putting all the classes in separate files. I have a base class Circle and a derived class Cylinder.
What I'm stuck on is trying to display on the screen the result of my calculated area and volume for an object B of a Cylinder type. I found a way to do that for a Circle, though it doesn't work for my Cylinder.
circle.h
#pragma once
#include <iostream>
class Circle {
public:
float r;
Circle();
Circle(float r);
Circle circumference();
Circle area();
void view();
void getArea();
void getCircum();
};
circle.cpp
#include "circle.h"
#include <cmath>
using namespace std;
Circle::Circle() : r(5) {
cout << "Default constructor has been called for a circle\n";
}
Circle::Circle(float r) {
this->r = r;
cout << "Constructor with parameters has been called for a circle\n";
}
void Circle::view() {
cout << "Radius = " << r << endl;
}
Circle Circle::circumference() {
return 2 * M_PI * r;
}
Circle Circle::area() {
return M_PI * pow(r, 2);
}
void Circle::getArea() {
cout << "Area = " << r << " m^2";
}
void Circle::getCircum() {
cout << "Circumference = " << r << " m";
}
cylinder.h
#pragma once
#include <iostream>
#include "circle.h"
class Cylinder : public Circle {
public:
float h;
Cylinder();
Cylinder(float r, float h);
void view();
double area();
double volume(float r, float h);
void getArea();
void getVolume();
};
cylinder.cpp
#include "cylinder.h"
#include <cmath>
using namespace std;
Cylinder::Cylinder() : h(7) {
cout << "Default constructor has been called for a cylinder\n";
}
Cylinder::Cylinder(float r, float h) : Circle(r) {
this->h = h;
cout << "Constructor with parameters has been called fo a cylinder\n";
}
void Cylinder::view() {
Circle::view();
cout << "Height = " << h << endl;
}
double Cylinder::area() {
return 2 * M_PI * r * h;
}
double Cylinder::volume(float r, float h) {
return M_PI * pow(r, 2) * h;
}
void Cylinder::getArea() {
cout << "Area = " << h;
}
void Cylinder::getVolume() {
cout << "Volume = " << h;
}
main.cpp
#include <iostream>
#include "circle.h"
#include "cylinder.h"
using namespace std;
int main() {
Circle A;
A.view();
Circle A1(8);
A1.view();
Cylinder B;
B.view();
Cylinder B1(4, 6);
B1.view();
//A.area().getArea();
//cout << endl;
//A.circumference().getCircum();
//cout << endl;
//A1.area().getArea();
//cout << endl;
//A1.circumference().getCircum();
B.area().getArea();
return 0;
}
The error that I'm getting:
main.cpp: In function ‘int main()’:
main.cpp:26:14: error: request for member ‘getArea’ in ‘B.Cylinder::area()’, which is of non-class type ‘double’
26 | B.area().getArea();
| ^~~~~~~
I feel like neither my code in main() for instance B, nor my methods getArea() and getVolume() in class Cylinder, are correct. And there is probably a better approach to do the same for an object A and A1 of a Circle type, though the code I commented out actually works.
I know that this is a dumb question, and such things should be quite straightforward, but I am trying to learn and would be grateful for any advice on how I can fix this.
Well, the reason you are getting the error message:
main.cpp: In function ‘int main()’:
main.cpp:26:14: error: request for member ‘getArea’ in ‘B.Cylinder::area()’, which is of non-class type ‘double’
26 | B.area().getArea();
| ^~~~~~~
Is because you are basically doing this:
auto _ = B.area();
So here, _ deduces to be a double, and then you do:
_.getArea();
You are trying to access a member function from a double, and double doesn't have any member functions.
You probably meant to do this instead:
auto x = B.area();
B.h = x;
B.GetArea();
This assigns the area of B.area() to a variable x, and assigns x to B.h. B's member function then gets called and outputs the area.
In your getArea() function, instead of saying:
cout << "Area = " << endl;
Just say:
cout << "Area = " << area() << endl;
Then in your main.cpp, just call B.getArea().
Hope this helps!
This question already has answers here:
Uninitialized variable behaviour in C++
(4 answers)
What happens when I print an uninitialized variable in C++? [duplicate]
(4 answers)
Calling function with variable that is being initialized [duplicate]
(1 answer)
Closed 5 months ago.
Here are the errors on the following code after the VS2022(v143) upgrade:
Could someone please suggest what is wrong here and how to fix it?
//Cricle properties problem
#include <iostream>
using namespace std;
float Qradius(float diameter)
{
float radius = diameter / 2;
return radius;
}
float Warea(float radius)
{
float area = (radius *radius) *3.14;
return area;
}
float Ecircumference(float diameter)
{
float circumference = 3.14 * diameter;
return circumference;
}
float Rarclength(float arcangle, float circumference)
{
float arclength = (circumference *arcangle) / 360;
return arclength;
}
int main()
{
float diameter, arcangle;
float area, circumference, arclength, radius;
cout << "Type the diameter ";
cin >> diameter;
cout << "Type the arcangle ";
cin >> arcangle;
cout << "The radius of the circle is " << Qradius(diameter) << endl;
cout << "The area is " << Warea(radius) << endl;
cout << "The circumference is " << Ecircumference(diameter) << endl;
cout << "The arc length is " << Rarclength(arcangle, circumference) << endl;
}
I solved the warnings and explained why they were coming up in the comments in the code. Also do not use using namespace std;
#include <iostream>
float Qradius(float diameter)
{
float radius = diameter / 2;
return radius;
}
float Warea(float radius)
{
// if no f is specified, the compiler assumes it is a double
// the warning tells you that it converts a double to float
// which could lead to loss of data (C4244)
float area = (radius *radius) * 3.14f;
return area;
}
float Ecircumference(float diameter)
{
// same as aboth
float circumference = 3.14f * diameter;
return circumference;
}
float Rarclength(float arcangle, float circumference)
{
float arclength = (circumference *arcangle) / 360;
return arclength;
}
int main()
{
float diameter, arcangle;
// area and arclength are unused (C4101)
float /*area,*/ circumference, /*arclength,*/ radius;
std::cout << "Type the diameter ";
std::cin >> diameter;
std::cout << "Type the arcangle ";
std::cin >> arcangle;
// radius and circumference is never set
// and later used without setting any value (C6001)
radius = Qradius(diameter);
circumference = Ecircumference(diameter);
std::cout << "The radius of the circle is " << radius << std::endl;
std::cout << "The area is " << Warea(radius) << std::endl;
std::cout << "The circumference is " << circumference << std::endl;
std::cout << "The arc length is " << Rarclength(arcangle, circumference) << std::endl;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 10 months ago.
This post was edited and submitted for review 10 months ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
**my project talk about Shape hierarchy for every shape needs Inheritance, Polymorphism and Files I/0
I did a simple thing of the requirements, but I did not do it 100%, such as requirements 1, 2, 3 or requirements 6 and 7, so I sent all the requirements, please help me**
All classes must have a color and name attributes, both of a string type and stored in the base class (Shape).
All 2D shapes must have area and perimeter attributes, both of double type and stored in their base class (Sahpe2D).
All 3D shapes must have surfaceArea and volume attributes, both of double type and stored in their base class (Shape3D),
readData(), print(), printToFile(ofstream &output), readFromFile(ifstream &input) functions must be implemented in all classes (base and derived), taking into consideration they will be used for polymorphism,
computeArea() and computePerimeter() functions must be implementer in all 2D shape classes (including their base class), taking into consideration their use in polymorphism,
computeSurfaceArea() and computeVolume() functions must be implemented in all 3D shape classes (including their base class), taking into consideration their use in polymorphism,
Requirements
For every class, you need to build a default/parametrized constructor,
The default constructors set the objects' data members to 1.0,
Parametrized constructors are used to set objects' data members using the values passed to the objects during instantiation
readData() function is used to read all the object's data members from the user
print() function is used to print all object's data to the screen,
Your program must be able to write all objects' data to the binary file "Shapes.dat", using the printToFile functions,
Your program should be able to read and append to the "Shapes.dat" file as needed, using the readFromFile functions,
Your main file must be able to store/retrieve data to/from output/input files depending on the user's choice,
It is not known how many objects will be added or their order of addition.
//Shapes.h
#pragma once
#include<iostream>
#include<fstream>
using namespace std;
class Shape {
public:
string color, name;
Shape()
{
cout << "Base Class is Shape for this element . \n";
}
};
//Shape2D.h
#pragma once
#include"shapes.h"
class Shape2D : public Shape {
public:
double area, perimeter;
Shape2D()
{
cout << "Parent Class is Shape2D for this element .\n";
}
};
//Shape3D.h
#pragma once
#include"shapes.h"
class Shape3D : public Shape {
public:
Shape3D()
{
cout << "Parent Class is Shape3D for this element .\n";
}
};
//Square.h
#include"shapes2D.h"
class Square : public Shape2D {
public:
Square()
{
cout << "Calculating square area and perimeter \n";
}
void computeArea(double side)
{
double area;
area = side * side;
print("Area", area);
printToFile("Area", area);
}
void computePerimeter(double side) {
double perimeter;
perimeter = 4 * side;
print("Perimeter", perimeter);
printToFile("Perimeter", perimeter);
}
void print(string x, double y)
{
cout << x << " of Square = " << y << "\n";
}
void printToFile(string x, double y)
{
ofstream ofs;
ofs.open("shapes.dat");
if (!ofs) {
cout << "Error opening file" << endl;
}
cout << "Shapes.dat file updated .";
ofs << x << " of Square = " << y << "\n";
}
};
//Triangle.h
#include"shapes2D.h"
class Triangle : public Shape2D {
public:
Triangle()
{
cout << "This is a Triangle\n";
}
void computeArea(double base, double height) {
double area;
area = (height * base) / 2;
print("Area", area);
printToFile("Area", area);
}
void computePerimeter(double base, double height) {}
void print(string x, double y)
{
cout << x << " of Triangle = " << y << "\n";
}
void printToFile(string x, double y)
{
ofstream ofs;
ofs.open("shapes.dat");
if (!ofs) {
cout << "Error opening file" << endl;
}
cout << "Shapes.dat file updated .";
ofs << x << " of Triangle = " << y << "\n";
}
};
//Sphere.h
#include"shapes3D.h"
class Sphere : public Shape3D {
public:
Sphere()
{
cout << "This is a Sphere\n";
}
void computeSurfaceArea(double radius) {
double area;
area = 4 * 3.14 * radius * radius;
print("Area", area);
printToFile("Area", area);
}
void computeVolume(double radius) {
double perimeter;
perimeter = (4 / 3) * (3.14 * radius * radius * radius);
print("Perimeter", perimeter);
printToFile("Perimeter", perimeter);
}
void print(string x, double y)
{
cout << x << " of Sphere = " << y << "\n";
}
void printToFile(string x, double y)
{
ofstream ofs;
ofs.open("shapes.dat");
if (!ofs) {
cout << "Error opening file" << endl;
}
cout << "Shapes.dat file updated .";
ofs << x << " of Sphere = " << y << "\n";
}
};
//Hexagon.h
#include"shapes2D.h"
class Hexagon : public Shape2D {
public:
Hexagon()
{
cout << "This is a Hexagon\n";
}
void computeArea(double side) {
double area;
area = 3 * sqrt(3) * side * side / 2;
print("Area", area);
printToFile("Area", area);
}
void computePerimeter(double side) {
double perimeter;
perimeter = 6 * side;
print("Perimeter", perimeter);
printToFile("Perimeter", perimeter);
}
void print(string x, double y)
{
cout << x << " of Hexagon = " << y << "\n";
}
void printToFile(string x, double y)
{
ofstream ofs;
ofs.open("shapes.dat");
if (!ofs) {
cout << "Error opening file" << endl;
}
cout << "Shapes.dat file updated .";
ofs << x << " of Hexagon = " << y << "\n";
}
};
//Cylinder.h
#include"shapes3D.h"
class Cylinder : public Shape3D {
public:
Cylinder()
{
cout << "This is a Cylinder\n";
}
void computeSurfaceArea(double radius, double height) {
double area;
area = (2 * 3.14 * radius) * (radius + height);
print("Surface Area", area);
printToFile("Surface Area", area);
}
void computeVolume(double radius, double height) {
double volume;
volume = 3.14 * radius * radius * height;
print("Volume", volume);
printToFile("Volume", volume);
}
void print(string x, double y)
{
cout << x << " of Cylinder = " << y << "\n";
}
void printToFile(string x, double y)
{
ofstream ofs;
ofs.open("shapes.dat");
if (!ofs) {
cout << "Error opening file" << endl;
}
cout << "Shapes.dat file updated .";
ofs << x << " of Cylinder = " << y << "\n";
}
};
//Cube.h
#include"shapes3D.h"
class Cube : public Shape3D {
public:
Cube()
{
cout << "This is a Cube\n";
}
void computeSurfaceArea(double side) {
double area;
area = 6 * side * side;
print("Surface Area", area);
printToFile("Surface Area", area);
}
void computeVolume(double side) {
double volume;
volume = side * side * side;
print("Volume", volume);
printToFile("Volume", volume);
}
void print(string x, double y)
{
cout << x << " of Cube = " << y << "\n";
}
void printToFile(string x, double y)
{
ofstream ofs;
ofs.open("shapes.dat");
if (!ofs) {
cout << "Error opening file" << endl;
}
cout << "Shapes.dat file updated .";
ofs << x << " of Cube = " << y << "\n";
}
};
//Cone.h
#include"shapes3D.h"
#include<cmath>
class Cone : public Shape3D {
double radius, height;
public:
Cone()
{
cout << "This is a Cone\n";
}
void computeSurfaceArea(double radius, double height) {
double area;
area = 3.14 * radius * (radius + sqrt(radius * radius + height * height));
print("Surface Area", area);
printToFile("Surface Area", area);
}
void computeVolume(double radius, double height) {
double volume;
volume = (3.14 * radius * radius * height) / 3;
print("Volume", volume);
printToFile("Volume", volume);
}
void print(string x, double y)
{
cout << x << " of Cone = " << y << "\n";
}
void printToFile(string x, double y)
{
ofstream ofs;
ofs.open("shapes.dat");
if (!ofs) {
cout << "Error opening file" << endl;
}
cout << "Shapes.dat file updated .";
ofs << x << " of Cone = " << y << "\n";
}
};
//Circle.h
#include"shapes2D.h"
class Circle : public Shape2D{
double radius;
public:
Circle()
{
cout << "Calculating circle area and perimeter \n";
}
void computeArea(double r)
{
double area;
area = 3.14 * r * r;
print("Area", area);
printToFile("Area", area);
}
void computePerimeter(double r) {
double perimeter;
perimeter = 2 * 3.14 * r;
print("Perimeter", perimeter);
printToFile("Perimeter", perimeter);
}
void print(string x, double y)
{
cout << x << " of Square = " << y << "\n";
}
void printToFile(string x, double y)
{
ofstream ofs;
ofs.open("shapes.dat");
if (!ofs) {
cout << "Error opening file" << endl;
}
cout << "Shapes.dat file updated .";
ofs << x << " of Circle = " << y << "\n";
}
};
//main.cpp
#include"Cone.h"
#include"Cube.h"
#include"Cylinder.h"
#include"Hexagon.h"
#include"sphere.h"
#include"square.h"
#include"Triangle.h"
#include "Circle.h"
int main()
{
Cylinder a;
Cube b;
Cone c;
double r, side, base, height;
int n;
cout << "Select any Number to calculate : ";
cout << "1. Circle \n";
cout << "2. Square\n";
cout << "3. Triangle\n";
cout << "4. Hexagon\n";
cout << "5. Sphere\n";
cout << "6. Cube\n";
cout << "7. Cylinder\n";
cout << "8. Cone\n";
cin >> n;
if (n == 1) {
Circle obj1;
cout << "Circle Radius";
cin >> r;
obj1.computeArea(r);
obj1.computePerimeter(r);
}
if (n == 2) {
Square obj2;
cout << "Square Side";
cin >> side;
obj2.computeArea(side);
obj2.computePerimeter(side);
}
if (n == 3) {
Triangle obj3;
cout << "Triangle Base";
cin >> base;
cout << "Triangle Height";
cin >> height;
obj3.computeArea(base, height);
// obj3.computePerimeter(base,height) ;
}
if (n == 4) {
Hexagon obj4;
cout << "Hexagon Side";
cin >> side;
obj4.computeArea(side);
obj4.computePerimeter(side);
}
if (n == 5) {
Sphere obj5;
cout << "Sphere Radius";
cin >> r;
obj5.computeSurfaceArea(r);
obj5.computeVolume(r);
}
if (n == 6) {
Cube obj6;
cout << "Cube Side";
cin >> side;
obj6.computeSurfaceArea(side);
obj6.computeVolume(side);
}
if (n == 7) {
Cylinder obj7;
cout << "Cylinder Radius";
cin >> r;
cout << "Cylinder Height";
cin >> height;
obj7.computeSurfaceArea(r, height);
obj7.computeVolume(r, height);
}
if (n == 8) {
Cone obj8;
cout << "Cone Radius";
cin >> r;
cout << "Cone Height";
cin >> height;
obj8.computeSurfaceArea(r, height);
obj8.computeVolume(r, height);
}
return 0;
}
There are quite a few things going on here.
You are trying to include header files all over the place. I dont know why you want/need them. It's fine (if you have those files defined somewhere) but for a simple case of defining some classes one monolithic file is ok.
You haven't satisfied the problem statement. It said "default/parametrized constructor" you have default constructors for each i.e. 'myClass()' but no parameterized one ex 'myClass(int heigh, int width)...' so you need to implement those so you can initialize shapes at construction time instead of setting them later.
The formatting is all over the place, I would recommend cleaning that up.
To your main question: "it appears to me that the classes are not defined What is the problem?"
You have defined classes, this is a class definition:
class Shape
{
public:
Shape()
{
cout << "Base Class is Shape for this element . \n";
}
private:
string color, name;
};
Down in main Shape myshape; is creating an object of type shape.
Here is a easy write up to follow as well:
https://www.geeksforgeeks.org/c-classes-and-objects/
I am trying to convert different coordinate systems. From polar to rectangular and vice versa. My pol_to_rect()function is not working properly. It is giving very small values(~10^(-44)) after converting and also before converting. There might be some problem while using the sin() and cos() functions. The rect_to_pol() is working fine for positive values.
Edit - When I changed atan() to atan2() how can I incorporate other values of x and y.
#include <iostream>
#include <cmath>
using namespace std;
#define PI 3.1415926
class Polar; // Forward declaration
class Rectangular {
private:
float x, y;
public:
Rectangular() {} // default constructor
Rectangular(float mv_x, float mv_y) {
x = mv_x;
y = mv_y;
}
void showData() const;
Polar rect_to_pol();
float& get_x() {
return x;
}
float& get_y() {
return y;
}
};
void Rectangular::showData() const {
cout << "--Rectangular--" << endl;
cout << "x: " << x << "\t" <<"y: " << y << endl;
}
class Polar {
private:
float r;
float theta;
public:
Polar() {} // default constructor
Polar(float mv_r, float mv_theta) {
r = mv_r;
theta = mv_theta;
}
void showData();
Rectangular pol_to_rect();
float& get_r(){
return r;
}
float& get_theta() {
return theta;
}
};
void Polar::showData() {
cout << "--Polar--" << endl;
cout << "r:" << r << "\t" << "Theta(Radians):" << theta << endl;
}
Rectangular Polar::pol_to_rect() {
Rectangular temp;
temp.get_x() = r * cos(theta*(PI/180.0)); // in degrees
temp.get_y() = r * sin(theta*(PI/180.0));
return temp;
}
Polar Rectangular::rect_to_pol() {
Polar temp;
temp.get_r() = sqrt(pow(x, 2) + pow(y, 2));
temp.get_theta() = atan2(y, x);
return temp;
}
int main()
{
Rectangular r1(-1, -1), r2;
Polar p1(12.0, 30.0), p2;
r1.showData();
p2 = r1.rect_to_pol();
cout << "After Conversion (RECT TO POLAR)->" << endl;
p2.showData();
p1.showData();
r2 = p1.pol_to_rect();
cout << "After Conversion (POLAR TO RECT)" << endl;
r2.showData();
return 0;
}
Why am I getting the address in the output. Rather I should get the Output Length= (value input by user) , Width = (value input by user).
As in the main body of program after getting input R1.getdata() , ptr->result() should display the result of Rectangle class.
#include <iostream>
using namespace std;
class Rectangle {
protected:
float length;
float width;
public:
void getdata() {
cout << "Enter length and width= ";
cin >> length >> width;
}
void result() {
cout << "Length = " << length << "\nWidth = " << width << endl;
}
};
class Area : public Rectangle {
private:
float area;
public:
void calc_area() { area = length * width; }
void result() { cout << "Area = " << area << endl; }
};
class Perimeter : public Rectangle {
private:
float perimeter;
public:
void calc_peri() { perimeter = 2 * (length + width); }
void result() { cout << "Perimeter = " << perimeter << endl; }
};
void main() {
Rectangle R1;
Area A1;
Perimeter P1;
Rectangle *ptr;
R1.getdata();
ptr = &A1;
ptr->result();
}
You are getting the wrong values, because you are calling ptr->result(); on a uninitialized Area object (A1), which has been upcasted from pointer to Rectangle object.
The values the user inputs though are used in the R1 object, which you then don't use anymore. Moreover, you should make the result() method virtual.
Lastly, the syntax for calling base class method on a pointer to an inheriting class is: ptr->Rectangle::result();.
Below you will find your code with some fixes that demonstrate things I wrote about:
#include <iostream>
using namespace std;
////////////////////////////////////////////////////////////////
class Rectangle {
protected:
float length;
float width;
public:
void getdata() {
cout << "Enter length and width= ";
cin >> length >> width;
std::cout << length << " " << width << std::endl;
}
virtual void result() {
cout << "(Rectangle) Length = " << length << "\nWidth = " << width
<< endl;
}
};
class Area : public Rectangle {
private:
float area;
public:
void calc_area() { area = length * width; }
void result() { cout << "Area = " << area << endl; }
};
class Perimeter : public Rectangle {
private:
float perimeter;
public:
void calc_peri() { perimeter = 2 * (length + width); }
void result() { cout << "Perimeter = " << perimeter << endl; }
};
int main() {
Rectangle R1;
Area* A1;
Perimeter P1;
Rectangle* ptr;
R1.getdata();
ptr = &R1;
A1 = static_cast<Area*>(ptr);
// or:
// A1 = (Area*)ptr;
ptr->Rectangle::result();
}
Ptr points to the address of a child of class Rectangle (the Area class) and therefore it calls the member (result) of the object it refers to (A1 of type Area)