I've been writing a program for CS class that's supposed to get the X and Y coordinates from the user, as well as the length of a square and the height of the cube, and it should then calculate the area of the square and the surface area and volume of the cube (plus some coordinates stuff but that's not a pressing issue right now)
I've written the test file and it compiled successfully, but I've been getting very long answers for the square and cube properties that are obviously wrong. Can anyone point out whatever logical errors I might have or if I have the access specification and relationship between the classes wrong?
Point.h
class Point
{
protected:
double Xint, Yint;
public:
Point();
void setX(double);
void setY(double);
double getX() const;
double getY() const;
};
Point.ccp
Point::Point()
{
Xint = 0;
Yint = 0;
}
void Point::setX(double x)
{ Xint = x; }
void Point::setY(double y)
{ Yint = y; }
double Point::getX() const
{ return Xint; }
double Point::getY() const
{ return Yint; }
Square.h
#include "Point.h"
class Square : public Point
{
protected:
Point lowerLeft;
double sideLength;
public:
Square(double sideLength, double x, double y) : Point()
{
sideLength = 0.0;
x = 0.0;
y = 0.0;
}
void setLowerLeft(double, double);
void setSideLength(double);
double getSideLength() const;
double getSquareArea() const;
};
Square.ccp
#include "Square.h"
void Square::setLowerLeft(double x, double y)
{
lowerLeft.setX(x);
lowerLeft.setY(y);
}
void Square::setSideLength(double SL)
{ sideLength = SL; }
double Square::getSideLength() const
{ return sideLength; }
// Calculate the area of square
double Square::getSquareArea() const
{ return sideLength * sideLength; }
Cube.h
#include "Square.h"
class Cube : public Square
{
protected:
double height;
double volume;
public:
Cube(double height, double volume) : Square(sideLength, Xint, Yint)
{
height = 0.0;
volume = 0.0;
}
double getSurfaceArea() const;
double getVolume() const;
};
Cube.ccp
#include "Cube.h"
// Redefine GetSquareArea to calculate the cube's surface area
double Cube::getSurfaceArea() const
{ return Square::getSquareArea() * 6; }
// Calculate the volume
double Cube::getVolume() const
{ return getSquareArea() * height; }
"Can anyone point out whatever logical errors I might have or if I have the access specification and relationship between the classes wrong?"
Well, from our well known 3-dimensional geometry a cube is made up from exactly 6 squares.
So how do you think inheriting a Cube class from a Square actually should work well?
You can easily define a Cube class by means of a fixed Point (e.g. the upper, left, front corner) and a fixed size of the edge length.
If you really want and need to, you can add a convenience function for your Cube class, that returns all of the 6 Squares it consist of in 3 dimensional space:
class Cube {
public:
Cube(const Point& upperLeftFrontCorner, double edgeLength);
std::array<Square,6> getSides() const;
};
Related
I am trying to calculate area of all shapes (rectangle, rhombus, triangle, circle) through using virtual and override methods. But when I execute the code it returns 1 for the area for all shapes even though I have tried with the rectangle to alter it to input the given area multiple times in int main() it still only outputs "My figure type is My area is 1 My figure type is Triangle My area is 1 My figure type is Circle My area is 1 My figure type is Rhombus My area is 1"
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
class Figure
{
protected:
double x;
double y;
string type;
public:
Figure(double m_x, double m_y) : x{ m_x }, y{ m_y } {};
virtual double area(double x, double y) { return 0; };
Figure(double m_x, double m_y, double x = 0, double y = 0) { m_x = x; m_y = y; }
virtual void Print() const final;
Figure(const Figure& obj);
Figure() {};
};
class Rectangle : public Figure
{
public:
Rectangle(double x, double y)
{
this->x = x;
this->y = y;
type = " Rectangle";
double area();
}
double area(double x, double y) override {
return x * y;
}
Rectangle() {};
};
class Triangle : public Figure
{
public:
Triangle(double x, double y)
{
this->x = x;
this->y = y;
type = " Triangle";
double area();
}
double area(double x, double y)override {
return x * y / 2;
}
Triangle() {};
};
class Circle : public Figure
{
public:
Circle(double x, double y)
{
this->x = x;
this->y = y;
type = " Circle";
double area();
}
double area(double x, double y)override {
return pow(x, 2) * 3.14;
}
Circle() {};
};
class Rhombus : public Figure
{
public:
Rhombus(double x, double y)
{
this->x = x; this->y = y; type = " Rhombus"; double area();
}
double area(double x, double y)override {
return x * y / 2;
}
Rhombus() {};
};
void Figure::Print() const
{
cout << " My figure type is" << type
<< " My area is " << &Figure::area;
}
int main()
{
Rectangle rectangle;
rectangle.area(5.4,6.2);
rectangle.Print();
Triangle triangle(4.5,5.3);
triangle.Print();
Circle circle(6.6, 8.8);
circle.Print();
Rhombus rhombus(3.4,5.4);
rhombus.Print();
}
You are getting 1 because a valid function pointer is treated as true.
You should call the function area like Figure::area(x, y) instead of getting the address of the function area like &Figure::area.
it's simple. really.
When you do
rectangle.area(x, y);
you just return the value you obtain from the variables that you passed in. You never assign a value to the x and y of the actual rectangle. So when you do print the area of the rectangle you use its real x and y, which do not have a value assigned to them, hence resulting in a 1. it's the same for the other shapes.
I am working on a project for understanding classes and have hit a wall. If you have any advice about my syntax, please let me know where I am going wrong as I am still quite new to programming, but my question is to do with class inheritance. (A, C and D are included but pretty well completed).
My project:
A. Start with a point class... Override << (print values), +, - (to add and subtract point coordinates). I feel I have completed this portion.
B. Create a base class Shape. Shape will contain functions to calculate area, circumference and take point values to create a box that encapsulates the given shape. These will be overloaded by derived classes. Create a display() function that displays all relevant info (name, area, circumference and encapsulating box.
C. Build a heirarchy for shapes by making circle, square, triangle... add default and custom constructors whos arguments initialize the shapes using the correct number of point objects. I feel I have satisfied this too.
D. In main() Create an instance of each. Circle radius = to 23, square sides each = 25, Triangle sides = 10, 20 and 30 (very flat triangle, area = 0). Define each to contain the origin (0, 0). Display all the info. I feel I have completed this (minus the display function).
My question is (and where I am struggling), "How do I properly make/access functions from a base class (shape) to return meaningful information."
Do I literally just make them all virtual since some classes dont have the same information as others? (like Area() and Circumference()?)
#include <iostream>
#include <cmath>
using namespace std;
class Point {
public:
int x, y;
Point() {
x = 0;
y = 0;
}
Point(int x, int y): x(x), y(y) {} // constructor
friend ostream& operator<<(ostream& out, const Point number) { //Involves ostream to output the numbers
out << "(" << number.x << ", " << number.y << ")"; //that were input into the x and y values of Point.
return out;
}
friend Point operator+(Point first, Point second) { //Takes two mathematical vectors and tells the compiler
Point add; // to add the x values together and the y values together
add.x = first.x + second.x;
add.y = first.y + second.y;
return add;
}
friend Point operator-(Point first, Point second) { // same as above but with subtraction.
Point subtract;
subtract.x = first.x - second.x;
subtract.y = first.y - second.y;
return subtract;
}
};
class Shape {
protected:
float height, width;
public:
Shape() {
height = 0;
width = 0;
}
Shape(float h, float w) {
height = h;
width = w;
}
/*
int Display() {
//Do something..... Create a display function
return 0;
}
int BoundingBox() {
//Do something again......
return 0;
}
*/
virtual float Area() const = 0;
virtual float Circumference() const = 0;
virtual ~Shape() {};
};
class Circle: public Shape {
Point center;
float radius;
public:
Circle(): Shape() {};
Circle (Point p1, float r) { //Takes center point object, and given radius.
center = p1;
radius = r;
}
virtual float Area() const override { // Calculates circle area
return(M_PI * radius * radius);
}
virtual float Circumference() const override { // Calculates circumference
return(float (M_PI * 2 * radius));
}
virtual ~Circle() {};
};
class Square: public Shape {
Point first, second, third, fourth;
public:
Square(): Shape() {};
Square(Point p1, Point p2, Point p3, Point p4) { // Takes four point arguments and initializes them
first = p1;
second = p2;
third = p3;
fourth = p4;
height = second.x - first.x; //calculates the height and width from points
width = third.y - first.y;
}
virtual float Circumference() const override {
return 0; //Errors without the return statement
}
virtual float Area() const override{ // Calculates area by measuring the difference between given points
return(height * width);
}
virtual ~Square() {};
};
class Triangle: public Shape {
Point first, second, third;
public:
Triangle(): Shape() {};
Triangle(Point p1, Point p2, Point p3) { // Takes three point arguments and initializes them
first = p1;
second = p2;
third = p3;
height = third.y - first.y;// due to the nature of the question, this only works for flat triangles.
width = second.x - first.x;
}
virtual float Circumference() const override {
return 0; //Errors without the return statement
}
virtual float Area() const override {
return ((height * width) / 2);
}
virtual ~Triangle() {};
};
int main() {
Point p1(0, 0), p2(25, 0), p3(0, 25), p4(25, 25), p5(20, 0), p6(30, 0);
Circle c1 (p1, 23); // Circle with origin (0, 0) and a radius of 23
Square s1 (p1, p2, p3, p4); // Square with 4 points and the origin
Triangle t1 (p1, p5, p6); // Extraordinarily flat triangle with origin
cout << c1.Circumference() << endl;
cout << s1.Area() << endl;
cout << t1.Area() << endl;
}
At this point, I am feeling a bit lost of the woods and I am sure I have either created several mistakes along the way, or just a few, but regardless, I don't understand. Any advice would be appreciated!
edit: I have updated my code to include the recommendations to include virtual deconstructors, remove the getheight etc... statements, and add virtual to the derived functions
When you're working with inheritance, make sure to use a virtual destructor in all of your inherited classes, as well as the base class.
Your inherited virtual functions would benefit from being marked virtual and override too, in case you want to make further specializations.
You are overriding inherited functions, but then they do the same thing as the original, e.g. GetHeight(). That kinda defeats the point of inheriting those functions. They also do not need to be virtual if they aren't overridden.
Your derived classes would benefit from explicitly calling the base class's constructor. It will call the default constructor if you don't provide a specific constructor to call, which may or may not be the behaviour you intended - IMO it's safer to always provide the base class constructor you want!
As an example:
class Shape {
protected:
float height, width;
public:
Shape() {
height = 0;
width = 0;
}
Shape(float h, float w) {
height = h;
width = w;
}
virtual float Area() const = 0;
virtual float Circumference() const = 0;
virtual ~Shape() {};
};
class Circle: public Shape {
Point center;
float radius;
public:
Circle() : Shape() {};
Circle (Point p1, float r) : Shape() {
// Note you may wish to set the height and width here!
//Takes center point object, and given radius.
center = p1;
radius = r;
}
virtual float Area() const override { // Calculates circle area
return(M_PI * radius * radius);
}
virtual float Circumference() const override { // Calculates circumference
return(float (M_PI * 2 * radius));
}
virtual ~Circle() {};
};
I'm currently learning C++ by creating an N body simulation. In order to improve the number of bodies in my simulations I'm trying to implement the Barnes Hut approximation method. I'm actually coding a QuadTree structure in C++ (see below).
In order to construct my tree, I define three classes :
class Point : Corresponding to the bodies of my simulation with x and y position as attributes
class Rectangle : Corresponding to the properties of the leaves of my tree with position and dimension attributes
class QuadTree : Corresponding to my QuadTree and its children (leaves) and a Rectangle object, a vector of Point objects, four leaves objects (QuadTree) and a boolean to say if it contain leaves or not.
I wrote a main function where I define my tree with its boudaries and I divide it to make appear four leaves. Then I ask informations about my tree and the associated subtrees using the function void QuadTree::get_information(). This function allows to show some information about the current tree by displaying if it has children or not (divided), its boudaries, and the points it contains. If it has children, then we apply the function QuadTree::get_information() on each child and we repeat the process.
The problem is that the code give an error of this kind :
QuadTree : Capacity = 1, Divided (0:False, 1:True) = 0
Rectangle : Center Position = (0, 0), Width = 10, Height = 10
-------------------
-------------------
QuadTree : Capacity = 1, Divided (0:False, 1:True) = 1
Rectangle : Center Position = (0, 0), Width = 10, Height = 10
Northwest :
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Aborted (core dumped)
It seems that I have a problem of allocation memory. I think I make a bad use of the pointers NW, NE, SW, SE defined in the QuadTree class.
I'm not an expert of the utilisation of the memory allocation on C++, maybe I do a naive error. Do you see something wrong about the way a manage these pointers ? Could you suggest a solution to my problem and make run my algorithm ?
Thank you so much for your time ! :)
#include <iostream> //For console output/input
#include <fstream> //Allows to read/write files
#include <math.h> //Basic mathematic functions
#include <vector> //For dynamic arrays
#include <string> //Operations on strings
#include <tuple>
#include <cmath>
#include <sstream>
using namespace std;
class Point
{
public :
double get_x();
double get_y();
void set_x(double xp);
void set_y(double yp);
void get_information();
private :
double x;
double y;
};
double Point::get_x(){return x;}
double Point::get_y(){return y;}
void Point::set_x(double xp){x = xp;}
void Point::set_y(double yp){y = yp;}
class Rectangle
{
public :
double get_x();
double get_y();
double get_w();
double get_h();
void set_x(double xc);
void set_y(double yc);
void set_w(double wc);
void set_h(double hc);
bool contain(Point pt);
void get_information();
private :
double x;
double y;
double w;
double h;
};
double Rectangle::get_x() {return x;}
double Rectangle::get_y() {return y;}
double Rectangle::get_w() {return w;}
double Rectangle::get_h() {return h;}
void Rectangle::set_x(double xc) {x = xc;}
void Rectangle::set_y(double yc) {y = yc;}
void Rectangle::set_w(double wc) {w = wc;}
void Rectangle::set_h(double hc) {h = hc;}
class QuadTree
{
public :
Rectangle get_boundary();
int get_capacity();
void set_boundary(double xc, double yc, double wc, double hc);
void set_rectangle(Rectangle rect);
void set_capacity(int capacity);
void insert(Point pt);
void subdivide();
void set_divided();
bool is_divided();
void get_information();
QuadTree getNW();
QuadTree getNE();
QuadTree getSW();
QuadTree getSE();
void setNW(QuadTree nw);
void setNE(QuadTree ne);
void setSW(QuadTree sw);
void setSE(QuadTree se);
private :
QuadTree* NW=NULL;
QuadTree* NE=NULL;
QuadTree* SW=NULL;
QuadTree* SE=NULL;
Rectangle boundary;
vector<Point> p;
bool divided = false;
};
QuadTree QuadTree::getNW(){return *NW;}
QuadTree QuadTree::getNE(){return *NE;}
QuadTree QuadTree::getSW(){return *SW;}
QuadTree QuadTree::getSE(){return *SE;}
void QuadTree::setNW(QuadTree nw){NW=&nw;}
void QuadTree::setNE(QuadTree ne){NE=≠}
void QuadTree::setSW(QuadTree sw){SW=&sw;}
void QuadTree::setSE(QuadTree se){SE=&se;}
bool QuadTree::is_divided(){return divided;}
bool Rectangle::contain(Point pt)
{
return (pt.get_x() > get_x() - get_w()
and pt.get_x() < get_x() + get_w()
and pt.get_y() > get_y() - get_h()
and pt.get_y() < get_y() + get_h());
}
Rectangle QuadTree::get_boundary() {return boundary;}
void QuadTree::set_boundary(double xc, double yc, double wc, double hc)
{
boundary.set_x(xc);
boundary.set_y(yc);
boundary.set_w(wc);
boundary.set_h(hc);
}
//int QuadTree::get_capacity() {return n;}
//void QuadTree::set_capacity(int capacity) {n = capacity;}
void QuadTree::set_divided() {divided = true;}
void QuadTree::set_rectangle(Rectangle rect) {boundary = rect;}
void QuadTree::subdivide()
{
double xc = boundary.get_x();
double yc = boundary.get_y();
double wc = boundary.get_w();
double hc = boundary.get_h();
Rectangle nw;
nw.set_x(xc-wc/2.);
nw.set_y(yc+hc/2.);
nw.set_w(wc/2.);
nw.set_h(hc/2.);
Rectangle ne;
ne.set_x(xc+wc/2.);
ne.set_y(yc+hc/2.);
ne.set_w(wc/2.);
ne.set_h(hc/2.);
Rectangle sw;
sw.set_x(xc-wc/2.);
sw.set_y(yc-hc/2.);
sw.set_w(wc/2.);
sw.set_h(hc/2.);
Rectangle se;
se.set_x(xc-wc/2.);
se.set_y(yc+hc/2.);
se.set_w(wc/2.);
se.set_h(hc/2.);
QuadTree oNW, oNE, oSW, oSE;
oNW.set_rectangle(nw);
oNE.set_rectangle(ne);
oSW.set_rectangle(sw);
oSE.set_rectangle(se);
setNW(oNW);
setNE(oNE);
setSW(oSW);
setSE(oSE);
//NW = &oNW;
//NE = &oNE;
//SW = &oSW;
//SE = &oSE;
}
void QuadTree::insert(Point pt)
{
if (! get_boundary().contain(pt) ) {cout<<"Hello 1"<<endl; return; }
if (p.size() < 1)
{
cout<<"Hello 2"<<endl;
p.push_back(pt); // Insert element at the end
}
else
{
if (!divided)
{
QuadTree::subdivide();
QuadTree::set_divided();
}
}
NW->insert(pt);
NE->insert(pt);
SW->insert(pt);
SE->insert(pt);
}
void Point::get_information(){cout<<"Point : x = "<<get_x()<<"; y = "<<get_y()<<endl;}
void Rectangle::get_information(){cout<<"Rectangle : Center Position = ("<<get_x()<<", "<<get_y()<<"), Width = "<<get_w()<<", Height = "<<get_h()<<endl;}
void QuadTree::get_information()
{
cout<<"QuadTree : Capacity = "<<" 1"<<", Divided (0:False, 1:True) = "<<divided<<endl;
boundary.get_information();
/*cout<<"Points_in : "<<endl;
int siz = p.size();
for (int ii=0; ii<siz; ii++)
{
p[ii].get_information();
}*/
if (divided) {
cout<<" Northwest : "<<endl;
getNW().get_information();
cout<<" Northeast : "<<endl;
getNE().get_information();
cout<<" Southwest : "<<endl;
getSW().get_information();
cout<<" Southeast : "<<endl;
getSE().get_information();
}
}
int main()
{
QuadTree tree;
tree.set_boundary(0., 0., 10., 10.);
tree.get_information();
cout<<"-------------------"<<endl;
tree.subdivide();
tree.set_divided();
cout<<"-------------------"<<endl;
tree.get_information();
}
Multiple markers at this line
- candidates are:
- no matching function for call to
'Coordinate::Coordinate()'
I am getting this error in the constructor of my class and I don't understand why. Here is the code involved:
RadialScan header
#ifndef RADIALSCAN_H_
#define RADIALSCAN_H_
#include "EasyBMP/EasyBMP.h"
#include <vector>
#include "Coordinate.h"
using namespace std;
class RadialScan {
vector<int> distanceTimeSeries;
vector<Coordinate> timeSeries;
BMP image;
Coordinate center;
Coordinate getNextPoint(Coordinate c);
bool isBlack(Coordinate c);
void computeTimeSeries();
public:
RadialScan(char* filename);
vector<int> getDistances();
vector<Coordinate> getCoordinates();
};
#endif
RadialScan class (all the methods are implemented, but the error is in the constructor and that's the code I'm providing):
#include "RadialScan.h"
RadialScan::RadialScan(char* filename){
image.ReadFromFile(filename);
int centerX = image.TellWidth()/2;
int centerY = image.TellHeight()/2;
center = Coordinate(centerX, centerY);
}
...
The error seems to be in the constructor. If I remove the constructor everything seems to compile correctly. If I delete the code inside the constructor I'm still getting the error. I don't understand why it keeps asking me for the Coordinate::Coordinate() constructor even when I don't have a coordinate object defined in the RadialScan(char* filename) constructor.
Additionally, these are the files for the Coordinate class:
header:
#ifndef COORDINATE_H_
#define COORDINATE_H_
class Coordinate {
int x;
int y;
public:
Coordinate(int x, int y);
void setX(int oneX);
void setY(int oneY);
int getX();
int getY();
double getMagnitude();
Coordinate operator-(const Coordinate&);
bool operator==(const Coordinate&);
Coordinate operator=(const Coordinate&);
};
#endif
cpp class:
#include "Coordinate.h"
#include <math.h>
Coordinate::Coordinate(int oneX, int oneY) {
x = oneX;
y = oneY;
}
//Setters
void Coordinate::setX(int oneX) {
x = oneX;
}
void Coordinate::setY(int oneY) {
y = oneY;
}
//Getters
int Coordinate::getX() {
return x;
}
int Coordinate::getY() {
return y;
}
double Coordinate::getMagnitude() {
return sqrt(x * x + y * y);
}
Coordinate Coordinate::operator-(const Coordinate& p) {
return Coordinate(x - p.x, y - p.y);
}
bool Coordinate::operator==(const Coordinate& p) {
return x == p.x && y == p.y;
}
Coordinate Coordinate::operator=(const Coordinate& p) {
return Coordinate(p.x, p.y);
}
Your constructor must look like
RadialScan::RadialScan(char* filename) : center (0, 0) {
image.ReadFromFile(filename);
int centerX = image.TellWidth()/2;
int centerY = image.TellHeight()/2;
center = Coordinate(centerX, centerY);
}
this because you did not implement default constructor and you can not create center object by default, so the only way is to call explicity Coordinate constructor with some default values.
I am learning OpenGL w/ C++. I am building the asteroids game as an exercise. I'm not quite sure how to override the constructors:
projectile.h
class projectile
{
protected:
float x;
float y;
public:
projectile();
projectile(float, float);
float get_x() const;
float get_y() const;
void move();
};
projectile.cpp
projectile::projectile()
{
x = 0.0f;
y = 0.0f;
}
projectile::projectile(float X, float Y)
{
x = X;
y = Y;
}
float projectile::get_x() const
{
return x;
}
float projectile::get_y() const
{
return y;
}
void projectile::move()
{
x += 0.5f;
y += 0.5f;
}
asteroid.h
#include "projectile.h"
class asteroid : public projectile
{
float radius;
public:
asteroid();
asteroid(float X, float Y);
float get_radius();
};
main.cpp
#include <iostream>
#include "asteroid.h"
using namespace std;
int main()
{
asteroid a(1.0f, 2.0f);
cout << a.get_x() << endl;
cout << a.get_y() << endl;
}
error I'm getting:
main.cpp:(.text+0x20): undefined reference to `asteroid::asteroid(float, float)'
You can use the : syntax to call the parent's constructor:
asteroid(float X, float Y) : projectile (x ,y);
Ok, just figured it out.
I actually don't have asteroid constructors defined because I thought they would inherit. But I think I have to do the following in asteroid.h:
asteroid(float X, float Y) : projectile(X, Y){];
You need a asteroid.cpp.
Even though inheriting from projectile, for non-default constructors (i.e., asteroid(float,float)), you still need to define the child class constructor.
You'll also need to define get_radius, as it's not defined in your base class.
Here's how that might look (I've taken the liberty of passing values for radius into both ctors):
#include "asteroid.h"
asteroid::asteroid(float r)
: projectile()
{
radius = r;
}
asteroid::asteroid(float x, float y, float r)
: projectile(x, y)
{
radius = r;
}
float asteroid::get_radius()
{
return radius;
}