C++ unexpected output when using operator overloading - c++

I am attempting to go through a "Circle" structure (basically a binary tree). Each circle has an centerX, centerY, radius, and two leaf nodes. These leaves will either both be null or both be not null. There will never be one null and one not null.
I am using operator overloading to print a circle to the output stream using the SVG file format. The following is the relevant code:
circle.h:
#include <set>
#include <iostream>
using namespace std;
class Circle {
private:
double centerX, centerY, radius;
Circle* c1;
Circle* c2;
public:
static const int PAGE_DIMENSION = 200;
static const int DEFAULT_MAX_RADIUS = 15;
Circle( double x, double y, double radius, Circle* r1, Circle* r2 );
Circle( double x, double y, double radius );
Circle();
int isLeaf() const;
double getCenterX() const;
double getCenterY() const;
double area() const;
double getRadius() const;
Circle* getFirstSubcircle() const;
Circle* getSecondSubcircle() const;
bool operator<( Circle& other );
Circle* operator()( double x_in, double y_in);
Circle& operator=( Circle& rhs);
Circle* operator,( Circle& other );
double distance( Circle& rhs );
// THESE FUNCTIONS ARE NOT CLASS MEMBERS
// THEY ARE DEFINED OUTSIDE OF THE CLASS
// BUT REQUIRE ACCESS TO PRIVATE FIELDS
friend ostream& operator<<(ostream& osInput, Circle& circle);
friend ostream& operator/(ostream& osInput, Circle& circle);
friend Circle* reduce( set<Circle*>& circles);
};
circle.cpp:
#include <math.h>
#include <time.h>
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <set>
#include <fstream>
#include "circle.h"
using namespace std;
Circle::Circle( double x, double y, double radius, Circle* r1, Circle* r2 )
{
centerX = x;
centerY = y;
this->radius = radius;
c1 = r1;
c2 = r2;
}
Circle::Circle( double x, double y, double radius )
{
centerX = x;
centerY = y;
this->radius = radius;
}
Circle::Circle()
{
srand(time(0));
int randomX = rand() % (PAGE_DIMENSION + 1);
int randomY = rand() % (PAGE_DIMENSION + 1);
int randomRadius = rand() % DEFAULT_MAX_RADIUS + 1;
centerX = randomX;
centerY = randomY;
radius = randomRadius;
}
Circle* Circle::getFirstSubcircle() const
{
return c1;
}
Circle* Circle::getSecondSubcircle() const
{
return c2;
}
int Circle::isLeaf() const
{
if (c1 == NULL && c2 == NULL) {
return 1;
}
return 0;
}
ostream& operator/(ostream& osInput, Circle& circle)
{
if (circle.isLeaf()) {
osInput << " <circle cx=\"" << circle.centerX << "\" cy=\"" << circle.centerY <<"\" radius=\"" << circle.radius << "\" style=\"fill:blue;stroke:black;stroke-width:.05;fill-opacity:.1;stroke-opacity:.9\"/>\n";
}
else {
osInput << " <circle cx=\"" << circle.centerX << "\" cy=\"" << circle.centerY <<"\" radius=\"" << circle.radius << "\" style=\"fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5\"/>\n";
Circle* firstCircle = circle.getFirstSubcircle();
Circle* secondCircle = circle.getSecondSubcircle();
osInput / *firstCircle;
osInput / *secondCircle;
}
}
test.cpp:
#include <iostream>
#include <fstream>
#include <set>
#include <string>
#include <stdlib.h>
#include "circle.h"
using namespace std;
int main( int argc, char** argv ) {
Circle* circ2_1 = new Circle(45, 65, 3);
Circle* circ2_2 = new Circle(56, 55, 3);
Circle* circ2 = new Circle(11, 21, 8, circ2_1, circ2_2);
Circle* circ3 = new Circle(7, 7, 7);
Circle* circ4 = new Circle(10, 25, 11, circ2, circ3);
cout / *circ4;
}
When I run the code as it is above, I get the following as output:
<circle cx="10" cy="25" radius="11" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
<circle cx="11" cy="21" radius="8" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
<circle cx="45" cy="65" radius="3" style="fill:blue;stroke:black;stroke-width:.05;fill-opacity:.1;stroke-opacity:.9"/>
<circle cx="56" cy="55" radius="3" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
The following output is what I am expecting (based on the code within main):
<circle cx="10" cy="25" radius="11" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
<circle cx="11" cy="21" radius="8" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
<circle cx="45" cy="65" radius="3" style="fill:blue;stroke:black;stroke-width:.05;fill-opacity:.1;stroke-opacity:.9"/>
<circle cx="56" cy="55" radius="3" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
<circle cx="7" cy="7" radius="7" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
If I switch the last couple lines of code within the "ostream& operator/" function within the circle.cpp to the following:
osInput / *secondCircle;
osInput / *firstCircle;
The output will then be:
<circle cx="10" cy="25" radius="11" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
<circle cx="7" cy="7" radius="7" style="fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5"/>
Again, this is not what I am expecting. The issue seems to be that it is only appending to ostream the first circle that is that is listed in the code, whether it is "firstCircle" or "secondCircle" that appears first. Am I wrong in thinking that it should produce the output I am expecting? Any ideas pointing me in the right direction would be much appreciated, as I have tried everything I can think of.

For the 3-parameter Circle constructors, you don't initialize the c1 or c2 members. This will be Undefined Behavior when you later try to dereference these values (likely a crash).

Related

Unexpected output when dealing with operator overloading in C++ using

I am attempting to go through a "Circle" structure (basically a binary tree). Each circle has an centerX, centerY, radius, and two leaf nodes. These leaves will either both be null or both be not null. There will never be one null and one not null.
I am using a variety of operator overloading functions. I am attempting to do one with the "," operator but I am having trouble actually getting the function to hit.
Below is the relevant code:
circle.h:
#include <set>
#include <iostream>
using namespace std;
class Circle {
private:
double centerX, centerY, radius;
Circle* c1;
Circle* c2;
public:
static const int PAGE_DIMENSION = 200;
static const int DEFAULT_MAX_RADIUS = 15;
Circle( double x, double y, double radius, Circle* r1, Circle* r2 );
Circle( double x, double y, double radius );
Circle();
int isLeaf() const;
double getCenterX() const;
double getCenterY() const;
double area() const;
double getRadius() const;
Circle* getFirstSubcircle() const;
Circle* getSecondSubcircle() const;
bool operator<( Circle& other );
Circle* operator()( double x_in, double y_in);
Circle& operator=( Circle& rhs);
Circle* operator,( Circle& other );
double distance( Circle& rhs );
// THESE FUNCTIONS ARE NOT CLASS MEMBERS
// THEY ARE DEFINED OUTSIDE OF THE CLASS
// BUT REQUIRE ACCESS TO PRIVATE FIELDS
friend ostream& operator<<(ostream& osInput, Circle& circle);
friend ostream& operator/(ostream& osInput, Circle& circle);
friend Circle* reduce( set<Circle*>& circles);
};
circle.cpp
#include <math.h>
#include <time.h>
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <set>
#include <fstream>
#include "circle.h"
using namespace std;
class CirclePair {
public:
Circle* c1;
Circle* c2;
double distance;
CirclePair(Circle* c1, Circle* c2, double distance)
{
this->c1 = c1;
this->c2 = c2;
this->distance = distance;
}
};
Circle::Circle( double x, double y, double radius, Circle* r1, Circle* r2 )
{
centerX = x;
centerY = y;
this->radius = radius;
c1 = r1;
c2 = r2;
}
Circle::Circle( double x, double y, double radius )
{
centerX = x;
centerY = y;
this->radius = radius;
c1 = NULL;
c2 = NULL;
}
Circle::Circle()
{
unsigned seed = time(0);
srand(seed);
int randomX = rand() % (PAGE_DIMENSION + 1);
int randomY = rand() % (PAGE_DIMENSION + 1);
int randomRadius = rand() % DEFAULT_MAX_RADIUS + 1;
centerX = randomX;
centerY = randomY;
radius = randomRadius;
}
int Circle::isLeaf() const
{
if (c1 == NULL && c2 == NULL) {
return 1;
}
return 0;
}
double Circle::getCenterX() const
{
return centerX;
}
double Circle::getCenterY() const
{
return centerY;
}
double Circle::area() const
{
double pi = 3.14159265358979323846;
return ( pi * (radius * radius));
}
double Circle::getRadius() const
{
return radius;
}
Circle* Circle::getFirstSubcircle() const
{
return c1;
}
Circle* Circle::getSecondSubcircle() const
{
return c2;
}
double Circle::distance( Circle& rhs )
{
double diffX = rhs.getCenterX() - getCenterX();
double diffY = rhs.getCenterY() - getCenterY();
return sqrt((diffX * diffX) + (diffY * diffY));
}
bool Circle::operator<( Circle& other )
{
cout << "Made it to operator <\n";
return area() < other.area();
}
Circle* Circle::operator()( double x_in, double y_in)
{
Circle* c = new Circle();
return c;
}
Circle& Circle::operator=( Circle& rhs)
{
cout << "Made it to operator =";
Circle* c = new Circle();
return *c;
}
Circle* Circle::operator,( Circle& other )
{
cout << "Made it to operator ,";
double distanceBetween = distance(other);
double c3Radius, c3CenterX, c3CenterY;
Circle* c3;
if (distanceBetween + getRadius() <= other.getRadius())
{
c3Radius = other.getRadius();
c3CenterX = other.getCenterX();
c3CenterY = other.getCenterY();
}
else
{
double theta = 0.5 + ((other.getRadius() - getRadius()) / (2 * distanceBetween));
c3Radius = (distanceBetween + getRadius() + other.getRadius()) / 2;
c3CenterX = ((1 - theta) * getCenterX() + theta * other.getCenterX());
c3CenterY = ((1 - theta) * getCenterY() + theta * other.getCenterY());
}
c3 = new Circle(c3CenterX, c3CenterY, c3Radius, this, &other);
return c3;
}
ostream& operator<<(ostream& osInput, Circle& circle)
{
osInput << "[ " << circle.centerX << ", " << circle.centerY << ", " << circle.radius << " ]\n";
return osInput;
}
ostream& operator/(ostream& osInput, Circle& circle)
{
if (circle.isLeaf()) {
osInput << " <circle cx=\"" << circle.centerX << "\" cy=\"" << circle.centerY <<"\" radius=\"" << circle.radius << "\" style=\"fill:blue;stroke:black;stroke-width:.05;fill-opacity:.1;stroke-opacity:.9\"/>\n";
}
else {
osInput << " <circle cx=\"" << circle.centerX << "\" cy=\"" << circle.centerY <<"\" radius=\"" << circle.radius << "\" style=\"fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5\"/>\n";
Circle* firstCircle = circle.getFirstSubcircle();
Circle* secondCircle = circle.getSecondSubcircle();
osInput / *firstCircle;
osInput / *secondCircle;
}
}
Circle* reduce( set<Circle*>& circles)
{
Circle* removeCirc1, removeCirc2;
//while (circles.size() != 1)
//{
std::set<Circle*>::iterator circlesIterator = circles.begin();
std::set<Circle*>::iterator circlesIterator2 = circles.begin();
std::set<CirclePair*> setOfCirclePairs = {};
while (circlesIterator != circles.end())
{
Circle *current = *circlesIterator;
while (circlesIterator2 != circles.end())
{
Circle *current2 = *circlesIterator2;
if (current != current2)
{
CirclePair *currentPair = new CirclePair(current, current2, current->distance(*current2));
setOfCirclePairs.insert(currentPair);
bool testBool = *current2 < *current;
cout << testBool << "\n";
Circle* newC = *current , *current2;
}
circlesIterator2++;
}
circlesIterator++;
}
CirclePair* minDistancePair = NULL;
std::set<CirclePair*>::iterator circlePairs = setOfCirclePairs.begin();
while (circlePairs != setOfCirclePairs.end()) {
CirclePair *currentCP = *circlePairs;
if (minDistancePair == NULL)
{
minDistancePair = currentCP;
}
else
{
if (currentCP->distance <= minDistancePair->distance)
{
minDistancePair = currentCP;
}
}
cout << currentCP->c1->getCenterX() << " " << currentCP->c2->getCenterX() << " " << currentCP->distance << "\n";
circlePairs++;
}
//find lowest distance pair
cout << minDistancePair->distance << "\n";
//}
}
test.cpp:
#include <iostream>
#include <fstream>
#include <set>
#include <string>
#include <stdlib.h>
#include "circle.h"
using namespace std;
int main( int argc, char** argv ) {
Circle* circ = new Circle();
Circle* circ2_1 = new Circle(1, 2, 4);
Circle* circ2_2 = new Circle(134, 55, 3);
Circle* circ2 = new Circle(11, 21, 8, circ2_1, circ2_2);
Circle* circ3 = new Circle(145, 123, 8);
std::set<Circle*> setOfCircles { circ, circ2, circ3 };
Circle* completedCircle = reduce(setOfCircles);
}
The reduce function that is called within tests.cpp is where the code should be getting activated for the "," operation. The function is called "Circle* reduce( set<Circle*>& circles)" within the circle.cpp file. In this function, the following chunk of code is where some calls are made to the operator functions:
if (current != current2)
{
CirclePair *currentPair = new CirclePair(current, current2, current->distance(*current2));
setOfCirclePairs.insert(currentPair);
bool testBool = *current2 < *current;
cout << testBool << "\n";
Circle* newC = *current , *current2;
}
The testBool that is returned from using the "<" works correctly and triggers the "bool Circle::operator<( Circle& other )" function, but the "newC" circle assignment that is not working and the "Circle* Circle::operator,( Circle& other )" function is never being called. This confuses me as I am calling them both in the same fashion.
Any ideas on how to properly call the "," circle operator?
Operator , has lowest precedence of all, and therefore is the worst operator to be used in this manner: https://en.cppreference.com/w/cpp/language/operator_precedence
Since operator = actually has higher precedence, the effect of the problem line is closer to something like:
(Circle* newC = *current) , *current2;
But this won't trigger the overload as the left hand is now a pointer.
To achieve the desired effect you probably need to put braces around the pair:
Circle* newC = ( *current , *current2 );
The answer by Marc is correct: however I am going to recommend that the solution you should be looking for is don't overload operator,. I'm also going to recommend that you also don't overload operator< or operator() for your class, and that you don't overload operator/ for the ostream class.
On of the first question you should ask yourself when writing code is "what does it look like my code is trying to do?" Excessive use of operator overloading generally obfuscates the idea behind the code unless used very sparingly, e.g. even with your operator< function it isn't going to be immediately obvious that it compares the area of the circles. The operator() is also very confusing - I know you probably haven't implemented it yet but it seems like your gearing up to make a function which constructs a new circle; this is not going to be intuitive to anyone who reads it and has to guess what the difference between Circle c(x,y,r) and a subsequent c(x1,y1) is.
Overloading operators for the ostream class is a convention: << streams things 'to' the class and >> streams things 'from' the class. Trying to read code which has ostream / object is going to cause (almost) anyone who looks at it to do a double take.
Another problem, which you have already run into, is that operators have precedence which can lead to weird effects. With function calls, you know that the operands aren't going to magically disappear into operands of a different nearby function.
This is not a rant against you personally, and I have been guilty of thinking 'this would look much nicer if I just overloaded XYZ operator' myself as I am sure many people here have too, but taking a step back and realising that it actually makes the code much harder for other people to read is really important when writing code - especially C++ which has so many other interesting ways of tripping us up.

Creating a Class with 2 double values in C++

In C++ I am trying to create a class Point2D that contains two double values. All data members and functions should be public.
For Public Members there should be
double x
double y
For Constructors
the default constructor should initialize x and y to 0.0
Point2D(double in_x, double in_y)
sets x and y to in_x and in_y
For non-member Functions
void GetResult(Point2D p1, Point2D p2)
Prints x and y values for both
This is the code I have so far, can somebody please point out my errors?
Point2D.h
#ifndef POINT2D_H
#define POINT2D_H
class Point2D
{
public:
double x;
double y;
Point2D();
Point2D(double,double);
};
void GetResult(Point2D, Point2D);
#endif
Point2D.cpp
#include "Point2D.h"
#include <iostream>
using namespace std;
Point2D::Point2D()
{
x = 0.0;
y = 0.0;
}
Point2D::P1(double in_x, double in_y)
{
x = in_x;
y = in_y;
}
Point2D::P2(double in_x, double in_y)
{
x = in_x;
y = in_y;
}
void GetResult(Point2D P1, Point2D P2)
{
cout << P1.x << " " << P1.y << endl;
cout << P2.x << " " << P2.y << endl;
}
TestCheckPoint1.cpp
#include <iostream>
#include "Point2D.h"
using namespace std;
int main()
{
Point2D Point1;
Point1.x = 1.0;
Point1.y= 2.0;
Point2D Point2;
Point2.x= 1.0;
Point1.y= 2.0;
GetResult(Point1, Point2);
}
You are close, but it is clear you have a bit of misunderstanding about overloaded constructors and declaring instances of your class. For starters, you don't need the functions:
Point2D::P1(double in_x, double in_y)
{
x = in_x;
y = in_y;
}
Point2D::P2(double in_x, double in_y)
{
x = in_x;
y = in_y;
}
You simply need a single constructor for your Point2D class that takes two double values, e.g.
Point2D::Point2D(double in_x, double in_y)
{
x = in_x;
y = in_y;
}
Then in main() you need to declare and initialize default constuct two-instances of class Point2D providing the desired values to x and y before calling GetResult, e.g.
#include <iostream>
#include "Point2D.h"
using namespace std;
int main()
{
Point2D Point1 (1.0, 2.0);
Point2D Point2 (1.0, 2.0);
GetResult(Point1, Point2);
}
(note: You can provide an initializer lists that allow initialization of the class members, see Constructors and member initializer lists. You could provide an initializer list for your constructor with, e.g. Point2D() : x(0), y(0) {}; and the overload Point2D(double, double);. Your constructor definition would simply be Point2D::Point2D(double in_x, double in_y) : x(in_x), y(in_y) {} and the compiler would initialize x, y to 0, 0 if created with Point2D Point1; or set x, y to values provided as Point2D Point2 (1.0, 2.0);)
You did a very good job including the Header Guards around the contents of Point2D.h to prevent multiple inclusion if included in more than one file. The complete header and source files for Point2D could be:
#ifndef POINT2D_H
#define POINT2D_H
class Point2D
{
public:
double x;
double y;
Point2D();
Point2D(double,double);
};
void GetResult(Point2D, Point2D);
#endif
and
#include "Point2D.h"
#include <iostream>
using namespace std;
Point2D::Point2D()
{
x = 0.0;
y = 0.0;
}
Point2D::Point2D(double in_x, double in_y)
{
x = in_x;
y = in_y;
}
void GetResult(Point2D P1, Point2D P2)
{
cout << P1.x << " " << P1.y << endl;
cout << P2.x << " " << P2.y << endl;
}
Example Use/Output
Compiling and running would result in:
$ ./bin/TestCheckPoint1
1 2
1 2
Note: there is no need to using namespace std; in main() at all, and you really shouldn't include the entire standard namespace anywhere. Simply remove both calls and add std:: to your two cout calls and two calls to endl (or just use '\n' instead of std::endl;). See Why is “using namespace std;” considered bad practice?
Instead simply use:
void GetResult(Point2D P1, Point2D P2)
{
std::cout << P1.x << " " << P1.y << '\n';
std::cout << P2.x << " " << P2.y << '\n';
}
Look things over and let me know if you have further questions.

error: ‘cylinder’ was not declared in this scope

I wrote code in C++ in Xcode and receive:
error: ‘cylinder’ was not declared in this scope
Header file cylinder.h:
#include <iostream>
#ifndef cylinder_h
#define cylinder_h
#endif
#include "stdio.h"
using namespace std;
class cylinder
{
public:
// Constructors
cylinder();
cylinder(double r, double h);
// Accessors
double getRadius();
double getHeight();
void setRadius(double r);
void setHeight(double h);
double area();
double volume();
void write(std::ostream& output);
private:
double radius;
double height;
};
cylinder.cpp :
#include "cylinder.h"
double PI = 3.1415926535898;
#include "stdio.h"
using namespace std;
// Constructors
cylinder::cylinder()
{
radius = 0;
height = 0;
}
cylinder::cylinder(double r, double h)
{
radius = r;
height = h;
}
// Accessors
double cylinder::getRadius()
{
return radius;
}
double cylinder::getHeight()
{
return height;
}
// Setters
void cylinder::setRadius(double r)
{
radius = r;
}
void cylinder::setHeight(double h)
{
height = h;
}
// Calculations
double cylinder::area()
{
return 2 * PI * radius * radius + 2 * PI * radius * height;
}
double cylinder::volume()
{
return PI * radius * radius * height;
}
main.cpp:
#include <iostream>
using namespace std;
#include <string>
#include "cylinder.h"
#include <iomanip>
#include "sphere.h"
#include "prism.h"
#include "cone.h"
#include "pyramid.h"
#include <cstdlib>
int main()
{
double radius, height,sradius,length,width,rheight,cheight,cradius,pheight,plength;
cout << "Enter cylinder height and radius >>> ";
cin >> height >> radius;
cylinder one (radius, height);
cout << "The cylinder volume is " << setprecision(2)<<fixed<<one.volume () << endl;
cout << "The cylinder surface area is " << setprecision(2)<<fixed<<one.area () << endl;
cout <<"CYLINDER: "<<height<<", "<<radius<<endl;
}
I have been stuck for two days. I am so confused. I've already defined cylinder class, and I've tried many ways on the website. Is there anyone who can help me?
It's due tonight!
Sadly a method to try to find the answer and not the answer. It has been posted as an answer because I don't think I can fit it all in the bounds of a comment.
I have removed that which has not been provided, corrected the use if the include guard, shuffled a few things around, and commented out that which was not needed. Hopefully I have left a good enough explanation of what I did and why. If not, ask.
This compiles. I have not tested the logic.
What to do with it:
In main.cpp there are a bunch of files that were included but not provided. To get a working base, I have commented them out. Add them and rebuild the program one by one until the program stops compiling. If this does not make the problem obvious, it has at least reduced the search area.
Revised cylinder.h
// two lines below are an include guard. It prevents a header file from being included
// multiple times, heading off potentially recursive includes (a loop that
// causes the compiler to go forever) and chaos caused by redefining the same
// stuff multiple times.
#ifndef cylinder_h
#define cylinder_h
#include <iostream>
//#include "stdio.h" unused and should be #include <cstdio> when used in C++
//using namespace std; unused and very dangerous.
class cylinder
{
public:
// Constructors
cylinder();
cylinder(double r, double h);
// Accessors
double getRadius();
double getHeight();
void setRadius(double r);
void setHeight(double h);
double area();
double volume();
void write(std::ostream& output);
private:
double radius;
double height;
};
#endif // end of include guard moved to here
Revised cylinder.cpp
#include "cylinder.h"
double PI = 3.1415926535898;
//#include "stdio.h" not used
//using namespace std; dangerous and not used.
// Constructors
cylinder::cylinder()
{
radius = 0;
height = 0;
}
cylinder::cylinder(double r, double h)
{
radius = r;
height = h;
}
// Accessors
double cylinder::getRadius()
{
return radius;
}
double cylinder::getHeight()
{
return height;
}
// Setters
void cylinder::setRadius(double r)
{
radius = r;
}
void cylinder::setHeight(double h)
{
height = h;
}
// Calculations
double cylinder::area()
{
return 2 * PI * radius * radius + 2 * PI * radius * height;
}
double cylinder::volume()
{
return PI * radius * radius * height;
}
Revised main.cpp
#include <iostream>
//#include <string> not needed
#include "cylinder.h"
#include <iomanip>
// the following headers were not provided and may be containing bad code that
// breaks the OP's build. No way to tell. Add one and rebuild. If the program still
//compiles, the problem is likely elsewhere so add another and rebuild.
//#include "sphere.h"
//#include "prism.h"
//#include "cone.h"
//#include "pyramid.h"
//#include <cstdlib> not used
//using namespace std; used but use with caution. Instead, use only the pieces you need
using std::cout;
using std::cin;
using std::setprecision;
using std::fixed;
using std::endl;
// or explicitly state the namespace at each use.
// Eg. std::cout << "blah blah blah" << std::endl;
int main()
{
double radius, height;//,sradius,length,width,rheight,cheight,cradius,pheight,plength;
cout << "Enter cylinder height and radius >>> ";
cin >> height >> radius;
cylinder one (radius, height);
cout << "The cylinder volume is " << setprecision(2)<<fixed<<one.volume () << endl;
cout << "The cylinder surface area is " << setprecision(2)<<fixed<<one.area () << endl;
cout <<"CYLINDER: "<<height<<", "<<radius<<endl;
}
try to put #endif at the end of the header file
I think it's because of your multiples "using namespace std" , use only one , that one in the header file , and be sure to put it after all #includes
Here's your original code in a form that compiles and runs on my gnu/linux system. I tried to not to make many changes. I think you'll benefit from comparing your old code with new code to see what the minimal changes are, this may clear up some things for you.
After that, I show a more cleaned up version of the code, again I haven't really corrected it, especially the style and features used, but I've just tried to cut away a lot of the unnecessary things. I think realising what isn't neeed may also clear up some issues for you.
Code with minimal changes:
cylinder.h:
#include <iostream>
#ifndef cylinder_h
#define cylinder_h
#endif
#include "stdio.h"
using namespace std;
class cylinder
{
public:
// Constructors
cylinder();
cylinder(double r, double h);
// Accessors
double getRadius();
double getHeight();
void setRadius(double r);
void setHeight(double h);
double area();
double volume();
void write(std::ostream& output);
private:
double radius;
double height;
};
cylinder.cpp:
#include "cylinder.h"
double PI = 3.1415926535898;
#include "stdio.h"
using namespace std;
// Constructors
cylinder::cylinder()
{
radius = 0;
height = 0;
}
cylinder::cylinder(double r, double h)
{
radius = r;
height = h;
}
// Accessors
double cylinder::getRadius()
{
return radius;
}
double cylinder::getHeight()
{
return height;
}
// Setters
void cylinder::setRadius(double r)
{
radius = r;
}
void cylinder::setHeight(double h)
{
height = h;
}
// Calculations
double cylinder::area()
{
return 2 * PI * radius * radius + 2 * PI * radius * height;
}
double cylinder::volume()
{
return PI * radius * radius * height;
}
main.cpp:
#include <iostream>
using namespace std;
#include <string>
#include "cylinder.h"
#include <iomanip>
#include <cstdlib>
int main()
{
double radius, height,sradius,length,width,rheight,cheight,cradius,pheight,plength;
cout << "Enter cylinder height and radius >>> ";
cin >> height >> radius;
cylinder one (radius, height);
cout << "The cylinder volume is " << setprecision(2)<<fixed<<one.volume () << endl;
cout << "The cylinder surface area is " << setprecision(2)<<fixed<<one.area () << endl;
cout <<"CYLINDER: "<<height<<", "<<radius<<endl;
}
Here's the code with a bit more cleanup:
cylinder.h:
#ifndef cylinder_h
#define cylinder_h
#include <iostream>
class cylinder
{
public:
// Constructors
cylinder();
cylinder(double r, double h);
// Accessors
double getRadius();
double getHeight();
void setRadius(double r);
void setHeight(double h);
double area();
double volume();
void write(std::ostream& output);
private:
double radius;
double height;
};
#endif
cylinder.cpp:
#include "cylinder.h"
static const double PI = 3.1415926535898;
// Constructors
cylinder::cylinder() : radius(0.0), height(0.0)
{
}
cylinder::cylinder(double r, double h) : radius(r), height(h)
{
}
// Accessors
double cylinder::getRadius()
{
return radius;
}
double cylinder::getHeight()
{
return height;
}
// Setters
void cylinder::setRadius(double r)
{
radius = r;
}
void cylinder::setHeight(double h)
{
height = h;
}
// Calculations
double cylinder::area()
{
return 2 * PI * radius * radius + 2 * PI * radius * height;
}
double cylinder::volume()
{
return PI * radius * radius * height;
}
main.cpp:
#include <iostream>
#include <string>
#include <iomanip>
#include "cylinder.h"
using namespace std;
int main()
{
double radius, height;
cout << "Enter cylinder height and radius >>> ";
cin >> height >> radius;
cylinder one(radius, height);
cout << "The cylinder volume is " << setprecision(2) << fixed << one.volume() << endl;
cout << "The cylinder surface area is " << setprecision(2) << fixed << one.area() << endl;
cout << "CYLINDER: " << height << ", " << radius << endl;
}

c++ finding distance between 2 points

In my test program I have two points, and I want to find distance between them with my distancefrom. But I get answer 0.
Why does it give 0?
How can I fix it?
Point<2> v1;
// this should have {0.0, 0.0}
Point<2> v3 { list{2.0,3.0} };
float f = v1.distanceFrom(v3);
cout << f << endl;
I have a point.h file.
#ifndef POINT_H
#define POINT_H
#include <iostream>
#include <list>
#include <sstream>
#include <string>
using std::stringstream;
#include <cmath>
using namespace std;
template<unsigned short n>
class Point {
public:
list <float> coords = {0.0};
Point <n>() = default;
Point <n>(list<float> coords){
if (coords.size()!=n) {
throw string ("Vale koordinaatide arv");
}
this-> coords=coords;
}
string toString(){
string sone;
ostringstream ss;
sone.append("(");
auto it3= coords.begin();
while ((it3) != coords.end()){
ss << (*it3);
sone.append(ss.str());
ss.str("");
sone.append(",");
++it3;
}
sone.pop_back();
sone.append(")");
return sone;
}
float distanceFrom (Point <n> v){
float s=0;
list<float> coords;
auto it1= coords.begin();
auto it2= v.coords.begin();
while ((it1) != coords.end()){
s+=(*it1 -*it2)*(*it1-*it2);
it1++;
it2++;
}
return sqrt(s);
}
friend std::ostream& operator <<(std::ostream& out, const Point<n>& v)
{
out << "("<<"Test"<<")";
return out;
}
};
#endif
First, your coords list does not know you want its size to be n. Its size after default initialization like the following is 1:
list <float> coords = {0.0};
The proper way to construct it would be:
list <float> coords = list <float> (n, 0.0);
Second, you allocate a new coords inside the function distanceFrom:
list<float> coords;
This shadows the real coords of the point which you in fact want to use. Remove that line, and you will be fine.
#include<iostream>
#include<cstdlib>
#include<cmath>
using namespace std;
class pointDistance{
int x, y;
public:
pointDistance (int a, int b){
x =a;
y =b;
}
void pointShow(){
cout<<"The Point is ("<<x<<","<<y<<")"<<endl;
}
friend void Distance(pointDistance , pointDistance);
};
//formula of distance between two points:
//d =((x1^2 - x2^2) + (y1^2 - y2^2))^1/2
void Distance(pointDistance o1, pointDistance o2)
{
// pointDistance o3;
int d1,d2;
d1 = (o1.x -o2.x)*(o1.x -o2.x);
d2 = (o1.y - o2.y)*(o1.y - o2.y);
cout<<"So the distance between two point is "<< sqrt(d1+d2)<<endl;
}
int main(){
pointDistance one(4,5);
one.pointShow();
pointDistance two(0,6);
two.pointShow();
Distance(one, two);
return 0;
}

Have shape and circle class, and point class. Segmentation fault when creating circle with point class as one parameter

Here is my Shape.h. Ignore all the code that is commented out. That is from a version that I believe was incorrect but I left it in there in case I was wrong.
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <math.h>
#include "Point.h"
using namespace std;
class Shape {
public:
Shape() {}
virtual ~Shape() {}
/*
virtual float calcArea(const Shape& s) const = 0;
virtual float calcCircum(const Shape& s) const = 0;
virtual string calcBox(const Shape& s) const = 0;
virtual void display(const Shape& s) const = 0;
*/
virtual float calcArea() const = 0;
virtual float calcCircum() const = 0;
virtual string calcBox() const = 0;
virtual void display() const = 0;
};
class Circle : public Shape {
public:
int radius;
int pointX;
int pointY;
Point *middlePoint;
float PI;
Circle() : Shape() {
middlePoint = new Point(0,0);
radius = 0;
}
~Circle() {}
Circle(int rad, Point& p) : Shape() {
PI = 3.141592;
*middlePoint = p;
pointX = p.getX();
pointY = p.getY();
radius = rad;
}
// float calcArea(const Circle& s) const {
float calcArea() const {
float tempArea;
// tempArea = PI * s.radius * s.radius;
tempArea = PI * radius * radius;
return tempArea;
}
// float calcCircum(const Circle& s) const {
float calcCircum() const {
// int diameter = 2 * s.radius;
int diameter = 2 * radius;
float tempCircum;
tempCircum = PI * diameter;
return tempCircum;
}
// string calcBox(const Circle& s) const {
string calcBox() const {
// int x = s.pointX;
// int y = s.pointY;
// int r = s.radius;
int x = pointX;
int y = pointY;
int r = radius;
int tlX = x - r;
int tlY = y + r;
int blX = x - r;
int blY = y - r;
int trX = x + r;
int trY = y + r;
int brX = x + r;
int brY = y - r;
Point *topLeft = new Point(tlX,tlY);
Point *bottomLeft = new Point(blX,blY);
Point *topRight = new Point(trX,trY);
Point *bottomRight = new Point(brX,brY);
stringstream output;
string tempOut;
output << *topLeft << *bottomLeft << *topRight << *bottomRight;
tempOut = output.str();
return tempOut;
}
// void display(const Circle& s) const {
void display() const {
cout << "Class Name: Circle" << endl;
// float tmpArea = calcArea(s);
float tmpArea = calcArea();
cout << "Area = " << tmpArea << endl;
// cout << "Radius = " << s.radius << endl;
cout << "Radius = " << radius << endl;
// float tmpCircum = calcCircum(s);
float tmpCircum = calcCircum();
cout << "Circumference = " << tmpCircum << endl;
cout <<"Middle Point = " << middlePoint;
// string bbox = calcBox(s);
string bbox = calcBox();
cout <<"Bounding Box Points = " << bbox;
}
};
Here is my TMA4Question1.cpp code.
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <math.h>
#include "Shape.h"
int main() {
Point *circlePoint = new Point(10,-5);
Circle *mainCircle = new Circle(23,*circlePoint);
}
Ok. Yes this is a homework assignment for University. I'm not looking just for the answer, I would like to know why this program gives me a segmentation fault and how to correct it.
I know the error is in the Circle code, where I pass a pointer to the circlePOint in the constructor for the Circle class. I dont know why it generates a seg fault. I hope someone can provide some insight. Thanks.
Sorry if the code is messy. Had a hard time pasting it into here properly with 4 spaces and all that.
middlePoint is not allocated in your second Circle constructor. You are assigning a value to it before giving it some memory. As an aside, I don't see why anything there needs to be a pointer.
Why do you use pointers to Points inside your classes at all? You only generate memory leaks this way and (without your own copy operations) cause problems with as the midpoints could be shared by different circles.
PS: And it's not needed to have a PI value (even as non-const) in every circle - just use the constant from (afair) cmath for it.