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!
Related
I got an error in Visual Studio 2019, when building and using IntelliSense at the same time, which said that it expected a ';' (CODE: E0065 and the error is supposed to be on line 9), I am extremely confused because this is my first time getting an error like this when defining functions because it is also my first time defining functions in c++, I really don't know where I could be missing a semi colon. The program doesn't run.
#include <iostream>
using namespace std;
int main() {
const double pi{3.14159};
double calc_area_circle(double radius) {
return pi * (radius * radius);
}
void area_circle() {
double radius{};
cout << "Enter the radius of the circle: ";
cin >> radius;
cout << "The area of the circle with radius " << radius << " is " << calc_area_circle(radius) << endl;
}
return 0;
}
If any one could clear this up for me, I would really appreciate it.
Nesting of function definition (defining functions inside another functions) is not allowed in C++ unless you use lambda functions.
Put the function definitions outside the function
#include <iostream>
using namespace std;
const double pi{3.14159};
double calc_area_circle(double radius) {
return pi * (radius * radius);
}
void area_circle() {
double radius{};
cout << "Enter the radius of the circle: ";
cin >> radius;
cout << "The area of the circle with radius " << radius << " is " << calc_area_circle(radius) << endl;
}
int main() {
return 0;
}
or convert them to lambda function
#include <iostream>
using namespace std;
int main() {
const double pi{3.14159};
const auto calc_area_circle = [&](double radius) -> double {
return pi * (radius * radius);
};
const auto area_circle = [&]() {
double radius{};
cout << "Enter the radius of the circle: ";
cin >> radius;
cout << "The area of the circle with radius " << radius << " is " << calc_area_circle(radius) << endl;
};
return 0;
}
Note: these programs will do nothing because the defined functions are not called.
I am playing around with hierarchical objects and pointers and have written a base class Circle, then two classes Cylinder and Sphere that both derive from Circle.
When I run the program I get the error: double free or corruption (out): 0x00007fffffffddf0 ***
So I tried running the code through GDB. I found that the error occurs when I call the Cylinder destructor, which calls the virtual destructor for Circle. However I don't understand why this is happening.
From my research it seems this kind of error occurs when the code tries to deallocate memory that is not available to it.
I thought perhaps the destructor for Cylinder was causing the problem, since it is called first, so I commented out all of the Sphere and Circle object lines in main() and just used the Cylinder code.
When the destructor for the Cylinder pointer was called it resulted in a Segmentation Fault, so I am trying to access memory out of range.
Now I'm thoroughly confused.
Here is my code:
#include <iostream>
#include <cmath> // used for square
static constexpr float PI = 3.14159;
using namespace std;
class Circle{
protected:
float radius;
public:
float getRadius(){
return radius;
}
void setRadius(float r){
radius = r;
}
float calcCircleArea(){
return PI * pow(radius, 2);
}
float calcCircumference(){
return 2 * PI * radius;
}
Circle(){
// default constructor
}
Circle(float rad){
radius = rad; // overloaded constructor
}
virtual ~Circle(){ // virtual destructor
cout << "Destroying Circle Constructor" << endl;
}
};
class Cylinder: public Circle{
private:
float height;
public:
float getHeight(){
return height;
}
void setHeight(float h){
height = h;
}
float calcVol(){
float circleArea = calcCircleArea();
float vol = circleArea * height;
}
float calcSurfaceArea(){
float circum = calcCircumference();
float circleArea = calcCircleArea();
float cylSurfArea = (circleArea *2) + (circum * height);
}
Cylinder(){} // default constructor
Cylinder(float r, float h){ // overloaded constructor
radius = r;
height = h;
}
~Cylinder(){ // destructor
cout << "Destroying Cylinder Constructor" <<endl;
}
};
class Sphere : public Circle {
public:
float calcSurfaceArea(){
float r = getRadius();
return 4* PI * pow(r,2);
}
float calcVol(){
float r = getRadius();
return (4.0/3.0) * PI * pow(r,3);
}
Sphere(){} // default constructor
Sphere(float r){
radius = r;
}
~Sphere(){ // destructor
cout << "Destroying Sphere Constructor" << endl;
}
};
int main(){
cout << "Enter radius of circle and height of cyl:" << endl;
float r;
float h;
cin >> r >> h;
Sphere s1(r);
Cylinder cyl1(r,h);
Circle cir1(r);
//****************************
// Set up pointers
//****************************
Circle *circPtr;
circPtr = &cir1;
Sphere *sPtr;
sPtr = &s1;
Cylinder *cylPtr;
cylPtr = &cyl1;
cout << "Sphere vol : " << sPtr->calcVol() << endl;
cout << "Sphere SA : " << sPtr->calcSurfaceArea() << endl;
cout << "Cyl vol : " << cylPtr->calcVol() << endl;
cout << "Cyl SA : " << cylPtr->calcSurfaceArea() << endl;
cout << "Circle area : " << circPtr->calcCircleArea() << endl;
cout << "Circle circum : " << circPtr->calcCircumference() << endl;
cout << "sphere RADIUS : " << sPtr->getRadius() << endl;
cout << "cyl pointer VOLUME : " << cylPtr->calcVol() << endl;
cout << "circ pointer AREA: " << circPtr->calcCircleArea() << endl;
delete cylPtr;
delete sPtr;
return 0;
}
You're allocating your cylinder and sphere on the stack, then calling delete on pointers to them. This will destroy your objects twice. Once when you call delete, and once when they go out of scope (main ends).
Don't call delete on objects that you didn't create with new. Especially don't call delete on the address of stack objects.
Trying to get this homework figured out and I just keep hitting one wall after another. What I am getting now is the error message:
Error 1 error C2597: illegal reference to non-static member 'circleType::radius'
I have 2 header files, circleType.h and cylinderType.h and I need to out put results for shipping and painting costs that a user would enter. A little help before I go completely out of my mind ... Thank you.
circle.h
class circleType
{
public:
static void setRadius(double r);
double getRadius();
double area();
double circumference();
circleType(double r = 0);
private:
double radius;
};
void circleType::setRadius(double r)
{
if (r >= 0)
{
radius = r;
}
else
{
radius = 0;
}
}
double circleType::getRadius()
{
return radius;
}
double circleType::area()
{
return 3.1416 * radius * radius;
}
double circleType::circumference()
{
return 2 * 3.1416 * radius;
}
circleType::circleType(double r)
{
setRadius(r);
}
cylinderTyper.h
#include "circleType.h"
class cylinderType: public circleType
{
public:
static void setRadius(double r);
static double getRadius();
static double area();
static double circumference();
cylinderType(double r = 0);
private:
double radius;
};
main.cpp
#include "stdafx.h"
#include "cylinderType.h"
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
void enterData(int& cylinderBase,int& cylinerHeight, double& shipCost, double& paintCost);
int main()
{
cout << fixed << showpoint << setprecision(2);
int cylinderBase, cylinderHeight;
double sCost, pCost, shipCost, paintCost, volume, area = 0, circumference = 0;
enterData(cylinderBase, cylinderHeight, shipCost, paintCost);
cylinderType::setRadius(cylinderBase + cylinderHeight);
cylinderType::getRadius();
cylinderType::area();
cylinderType::circumference();
cout << "Cost of shipping: $" << circumference * shipCost << endl;
cout << "Cost of painting: $" << area * paintCost << endl;
system("pause");
return 0;
}
void enterData(int& cylinderBase, int& cylinderHeight, double& shipCost, double& paintCost)
{
cout << "Enter the base size of cylinder: ";
cin >> cylinderBase;
cout << endl;
cout << "Enter the hight size of cylinder: ";
cin >> cylinderHeight;
cout << endl;
cout << "Enter shipping cost per liter: ";
cin >> shipCost;
cout << endl;
cout << "Enter cost of painting per square foot: ";
cin >> paintCost;
cout << endl;
}
It's a very simple rule: static member functions can only access member variables that are static as well. That's because a static function isn't called against a specific object, so object members don't make sense in that context.
In your case, the static function setRadius is trying to modify the member variable radius which is not static. I suspect that you really don't want setRadius to be a static function.
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 9 years ago.
So far I've managed to fix my own errors, but this one is keeping me puzzled for a while now. If any of you have any hints, that would be greately appreciated! Thanks.
I'm using Eclipse on a Windows laptop, which gives me the following error after building:
undefined reference to `Point::Point()' circle.cpp
/Assignment4_1/IN4084MSc line 13 C/C++ Problem
All my files (main4_1.cpp, point.h, point.cpp, circle.h, circle.cpp) are part of a project (called Assignment4_1).
#include "point.h"
#include "circle.h"
#include <cmath>
using namespace std;
Circle::Circle(Point ct, double rd):Point(ct)
{
center = ct;
if(rd > 0)
{
radius = rd;
}
radius = -1;
}
Point Circle::get_center(){
return center;
}
double Circle::get_radius(){
return radius;
}
void Circle::print(){
cout << " <Circle(<Point(“"<<center.get_x()<<"”,“"<<center.get_y()<<"”)>,”"<<radius<<"”)>";
}
void Circle::print(string s){
cout << s;
print();
}
void Circle::println(){
print();
cout << endl;
}
void Circle::println(string s){
print(s);
cout << endl;
}
#ifndef CIRCLE_H_
#define CIRCLE_H_
#include <iostream>
#include "point.h"
using namespace std;
class Circle: public Point{
Point center;
double radius;
public:
Circle(Point ct, double rd);
Point get_center();
double get_radius();
void print();
void print(string s);
void println();
void println(string s);
};
#endif /* CIRCLE_H_ */
#include "point.h"
#include <cmath>
using namespace std;
Point::Point(double x, double y){
x_coord = x;
y_coord = y;
}
double Point::get_x(){
return x_coord;
}
double Point::get_y(){
return y_coord;
}
void Point::print(){
//post: has printed the contents of the Point object in the format
cout << "<Point( “ " << x_coord <<" ” , “ " << y_coord << " ” )>";
}
void Point::print(string s){
//post: has printed string s first, then printed the contents of the Point object
cout << s << " ";
print();
}
void Point::println(){
//post: has printed the contents of Point object, then moved the cursor to the next line
print();
cout << endl;
}
void Point::println(string s){
//post: has printed string s first, then printed the contents of the Point object, and moved the cursor to the next line
cout << s << " ";
println();
}
void Point::move(double dx, double dy){
// post: x_coord = x_coord + dx, y_coord = y_coord + dy
x_coord = x_coord + dx;
y_coord = y_coord + dy;
}
double Point::distance(Point that){
//post: returns the distance between this Point and that Point
return sqrt( pow(x_coord - that.get_x(),2) + pow(y_coord - that.get_y(),2) );
}
bool Point::equals(Point that){
//post : returns true if this Point and that Point have the same coordinates
return (x_coord = that.get_x());
}
#ifndef POINT_H_
#define POINT_H_
#include <iostream>
using namespace std;
class Point{
protected:
double x_coord;
double y_coord;
public:
Point(double x, double y);
Point();
double get_x();
double get_y();
void print();
void print(string s);
void println();
void println(string s);
void move(double dx, double dy);
double distance(Point that);
bool equals(Point that);
};
#endif /* POINT_H_ */
#include <iostream>
#include <cstdlib>
using namespace std;
#include "point.h"
#include "circle.h"
void test1(){
cout << "test1:" << endl;
Point p1 = Point(2,3);
cout << "Point p1 is created, the data of p1 = (2,3)" << endl;
cout << "p1.get_x() -> " << p1.get_x() << endl;
cout << "p1.get_y() -> " << p1.get_y() << endl << endl;
p1.println("p1.println() -> ");
cout << endl;
cout << "end test1" << endl << endl;
}
void test2(){
cout << "test2:" << endl;
cout << "Point p1 is created, the data of p1 = (2,3)" << endl;
cout << "Point p2 is created, the data of p2 = (0,0)" << endl;
Point p1 = Point(2,3);p1.println("p1.println() -> ");
Point p2 = Point(0,0);p2.println("p2.println() -> ");
cout << endl;
p1.println("p1 before move -> ");
cout << "p1.move(1,1)" << endl;p1.move(1,1);
p1.println("p1 after move -> ");
cout << endl;
cout << "p1.distance(p2) -> " << p1.distance(p2) << endl << endl;
cout << "p1.equals(p1) -> " << p1.equals(p1) << endl;
cout << "p1.equals(p2) -> " << p1.equals(p2) << endl;
cout << "end test2" << endl << endl;
}
int main(){
test1();
test2();
return 0;
}
The compiler is telling you to define
Point::Point()
which you have only declared in the Point class definition. A possible implementation would be to initialize both coordinates with 0.0:
Point::Point() : x_coord(0.0), y_coord(0.0) {}
You have to explicitly initialize the members in this case because built-in types do not get zero-initialized when default constructed.
#ifndef CIRCLE_H
#define CIRCLE_H
#include <QString>
#include <string>
using namespace std;
class Circle {
public:
//constructors
Circle();
Circle(double r);
//setter
void setRadius(double r);
//getter
double getRadius();
//calculate the diameter of a circle
double computeDiameter()const;
//calculate the area of a circle
double computeArea()const;
//calculate the Circumference of a circle
double computeCircumference()const;
//checks if radius of circle is bigger
**bool isBigger(const Circle& other) const;**
private:
//private data members
double m_Radius;
};
#endif // CIRCLE_H
#include "circle.h"
#include "math.h"
#include <iostream>
#include <QString>
#include <sstream>
using namespace std;
Circle::Circle()
{
m_Radius = 0;
}
Circle::Circle(double r)
{
m_Radius = r;
}
void Circle::setRadius(double r){
m_Radius = r ;
}
double Circle::getRadius(){
return m_Radius;
}
double Circle::computeDiameter()const{
return 2* m_Radius;
}
double Circle::computeArea()const {
return ( m_Radius* m_Radius*M_PI);
}
double Circle::computeCircumference()const {
return (2* m_Radius*M_PI);
}
#include <iostream>
#include <QTextStream>
#include "circle.h"
using namespace std;
int main(){
QTextStream cout(stdout);
Circle c1,c2; // input
c1.setRadius(3);
c2.setRadius(7);
cout << "Circle with radius " << c1.getRadius() << " has: " << endl;
cout<< "Diameter " << c1.computeDiameter() << " cm " <<endl;
cout<< "Area " << c1.computeArea() << " cm" <<endl;
cout<< "Circumference " << c1.computeCircumference()<< " cm " <<endl<<endl;
cout << "Circle with radius " << c2.getRadius() << " has: " << endl;
cout<< "Diameter " << c2.computeDiameter() << " cm " <<endl;
cout<< "Area " << c2.computeArea() << " cm" <<endl;
cout<< "Circumference " << c2.computeCircumference()<< " cm " <<endl<<endl;
return 0;
}
The function isBigger() returns true (or false) if the radius of the Circle instance on which the function is invoked is bigger (or smaller) than the radius of the Circle instance passed to the function.: I have no idea how to implement this function. Can someone explain this in simple english?
The implementation would look something like this:
bool Circle::isBiggerThan(const Circle& other) const
{
return m_Radius > other.m_Radius;
}
However, it is more idiomatic to use operators:
class Circle
{
// ...
friend bool operator >(Circle const &, Circle const &) const;
};
bool operator >(Circle const& lhs, Circle const& rhs) const
{
return lhs.m_Radius > rhs.m_Radius;
}
If you know your own radius (m_Radius or getRadius()) and the other circle's radius (other.getRadius()), then you can simply compare them to see which one has the bigger radius, like this:
bool Circle::isBigger(const Circle &other) const
{
return m_Radius > other.getRadius();
}
To make an example, if you have:
Circle c1;
Circle c2;
Then c1.isBigger(c2) should be true if and only if c1 has a greater radius than c2.
(I would probably have called the function isBiggerThan to make it easier to say aloud.)
Do you mean something like:
bool Circle::isBigger(const Circle& other) const
{
return m_Radius > other.getRadius();
}
This will simply check the current circle's radius (m_Radius) against the given circle's radius.