How to use overload operator as condition in a if statment? - c++

Here is the class
#include <fstream>
#include <cstdlib>
#include <math.h>
#include <iomanip>
#include <iostream>
using namespace std;
class Point {
protected:
int x, y;
double operator-(const Point &def){
return sqrt(pow((x-def.x),2.0)+
pow((y-def.y),2.0));
}
};
class Circle: public Point {
private:
int radius;
public:
Circle(){
this->x=x;
this->y=y;
this->radius=radius;
}
Circle(int x, int y, int radius){
this->x=x;
this->y=y;
this->radius=radius;
}
void printCircleInfo() {
cout << x << " " << y << " " << radius << " " ;
}
This is the operator I want to be the condition in my if statement.
bool operator==(const Circle &def){
return (x==def.x) & (y==def.y) & (radius==def.radius);
}
bool doIBumpIntoAnotherCircle(Circle anotherCircle){
if (anotherCircle.radius + radius >= *this - anotherCircle )
return true;
return false;
}
};
Here is main
int main(){
int x,y,radius;
const int SIZE = 13;
Circle myCircleArry[SIZE];
myCircleArry[0] = Circle(5,3,9);
cout << endl;
myCircleArry[0].printCircleInfo(); cout << " ; ";
ifstream Lab6DataFileHandle;
Lab6DataFileHandle.open("Lab6Data.txt");
while (!Lab6DataFileHandle.eof( )) {
for (int i = 1; i < SIZE; i++) {
Lab6DataFileHandle>>x;
Lab6DataFileHandle>>y;
Lab6DataFileHandle>>radius;
myCircleArry[i] = Circle(x,y,radius);
if (myCircleArry[0].doIBumpIntoAnotherCircle(myCircleArry[i])) {
myCircleArry[i].printCircleInfo(); cout << " ; ";
Here is the If statement
if ( operator==( Circle &def))
{cout <<"*";
}
}
}
}
Lab6DataFileHandle.close();
}
How do I use the overloaded operator as the condition of the if statement? If you need any clarification just ask other wise please leave an example in your answer.
Thank you for your time.

A == needs two arguments (even if the overload is a member), you would write the if as any other if statement:
if(circle1 == circle2) { ... }
and if there's a matching overload the compiler would transform that into something like:
if(circle1.operator ==(circle2)) { ... }

Related

Fuction-definition not allowed RetailItem

I got some problem when run my coding. I got 2 separate file to create RetailItem class and create main. I create both in project.
Below are main.cpp
//main
#include "retailitem.h"
#include <iostream>
#include <iomanip>
using namespace std;
using std::cout;
void displayItem(RetailItem *, const int);
int main()
{
const int Item = 3;
RetailItem ritem[Item] ={ { "Jacket", 12, 59.95 },
{ "Designer Jeans", 40, 34.95 },
{ "Shirt", 20, 24.95 } };
//cout << fixed << setprecision(2);
void displayItem(RetailItem *ritem, const int Item){
cout <<" DESCRIPTION UNITS ON HAND PRICE";
cout<<"=================================================================\n";
for (int i = 0; i < Item; i++)
{
cout << setw(12) << ritem[i].getDesc();
cout << setw(12) << ritem[i].getUnits();
cout << setw(8) << ritem[i].getPrice();
}
cout << "===================================================================";
}
return 0;
}
and there one more file retailitem.h
//RetailItem class
#include <string>
using namespace std;
class RetailItem
{
private:
string description;
int unitsOnHand;
double price;
public:
RetailItem(string,int,double);
void setDesc(string d);
void setUnits(int u);
void setPrice(double p);
string getDesc();
int getUnits();
double getPrice();
};
RetailItem::RetailItem(string desc, int units, double cost)
{
description = desc;
unitsOnHand = units;
price = cost;
}
void RetailItem::setDesc(string d)
{
description = d;
}
void RetailItem::setUnits(int u)
{
unitsOnHand = u;
}
void RetailItem::setPrice(double p)
{
price = p;
}
string RetailItem::getDesc()
{
return description;
}
int RetailItem::getUnits()
{
return unitsOnHand;
}
double RetailItem::getPrice()
{
return price;
}
when compile and run main,
[Error] a function-definition is not allowed here before '{' token
[Error] expected '}' at end of input
I don't know what to fix, how can I solve it?
The error message undoubtedly contained a line number that told you where the problem was. That's an important part of describing the problem. But here it happens to be obvious: void displayItem(RetailItem *ritem, const int Item){ is the start of a function definition. You can't define a function inside another function. Move this outside of main.

Using for_each to call a print function from a list of object

I need to use a for_each function to call the print function of each object in the list of objects shapeList. When I put function output as the final parameter of for_each, I get a "cannot determine which instance of overloaded function "output" is intended.
void output(Point* point)
{
point->print();
}
This is my output function for for_each
for_each(shapeList.begin(), shapeList.end(), output);
The for_each statement
I have looked at other solutions that involve using binds and lambdas, but this is a class assignment and I cannot use those methods.
Any help is greatly appreciated.
#include <iostream>
#include <string>
#include <fstream>
#include <list>
#include <algorithm>
#define sz 12
using namespace std;
class Point
{
private:
int x, y;
public:
Point() { }
Point(int a, int b)
:x(a), y(b) { }
// print function is pure virtual and that makes class Point an abstract class
// a pure virtual function can have prototype only without definition
// an abstract class can't be instantiated
// its derived class must override this function in order to be a real class
virtual void print() const = 0;
};
void Point::print() const
{
cout << "\nPoint: ( "
<< x
<< " , "
<< y
<< " )";
}
///////////////////////////////////////////////////////////////////
class Circle : public Point
{
private:
int radius;
public:
Circle() : Point() { }
Circle(int a, int b, int c)
:Point(a, b), radius(c) { }
virtual void print() const;
};
void Circle::print() const
{
cout << "\nCenter of the Circle is at: ";
Point::print();
cout << "\nRadius of the Circle is: "
<< radius;
}
/////////////////////////////////////////////////////////////////////
class Cylinder : public Circle
{
private:
int height;
char color[sz];
public:
Cylinder() { }
Cylinder(int a, int b, int r, int h, char clr[])
: Circle(a, b, r), height(h)
{ strcpy(color, clr); }
virtual void print() const;
};
void Cylinder::print() const
{
Circle::print();
cout << "\nHeight of Cylinder is: "
<< height
<< "\nColor of Cylinder is: "
<< color
<< endl;
}
void load_list(list<Point*>&, char*); //
void output(Point*&);
///////////////////////////////////////////////////////////////
int main()
{
char clr[10];
list<Point*> shapeList;////
load_list(shapeList, clr);
for_each(shapeList.begin(), shapeList.end(), output);
return 0;
}
void load_list(list<Point*>& ptList, char *ch)
{
char type;
int x, y, r, h;
ifstream infile("shapes.txt");
if (!infile)
{
cout << "\nCan not open input file.";
exit(1);
}
infile >> type;
while (infile)
{
if (type == 'c')
{
infile >> x >> y >> r;
ptList.push_back(new Circle(x,y,r));
}
else if (type = 'l')
{
infile >> x >> y >> r >> h >> ch;
ptList.push_back(new Cylinder(x, y, r, h, ch));
}
infile >> type;
}
}
void output(Point* point)
{
point->print();
}
You declare the function to take a pointer by reference(?) And the implementation takes a pointer.

Passing an object to a class and receiving no matching function error [duplicate]

This question already has answers here:
no default constructor exists for class
(5 answers)
Closed 5 years ago.
So, the problem happens around line 35 (where I call the edgeList constructor). Whenever it gets to that point I get the error
main.cpp:35:60: error: no matching function for call to 'point::point()'
Here's the problem area
class edgeList {
private:
point origin;
point terminal;
double weight;
public:
edgeList(const point& origin, const point& terminal) {
this->origin = origin;
this->terminal = terminal;
this->weight = findWeight(origin, terminal);
}
int findWeight(point origin, point terminal) {
return sqrt(pow((terminal.place('x') - origin.place('x')), 2) + pow((terminal.place('y') - origin.place('y')), 2));
}
};
And here's the full code
#include <iostream>
#include <string.h>
#include <fstream>
#include <vector>
#include <math.h>
using namespace std;
class point { //Creates the class that stores x and y coordinates
private:
double x;
double y;
public:
point(double x, double y) {
this->x = x;
this->y = y;
}
double place(char c) {
if (c == 'x') {
return this->x;
}
else if (c == 'y') {
return this->y;
}
else {
return -1;
}
}
};
class edgeList {
private:
point origin;
point terminal;
double weight;
public:
edgeList(const point& origin, const point& terminal) {
this->origin = origin;
this->terminal = terminal;
this->weight = findWeight(origin, terminal);
}
int findWeight(point origin, point terminal) {
return sqrt(pow((terminal.place('x') - origin.place('x')), 2) + pow((terminal.place('y') - origin.place('y')), 2));
}
};
int main(int argc, char *argv[]) {
double x;
double y;
int i = 0; //FIXME: DELETE THIS AFTER TESTING
vector<point> origin;
if (argv[1] == NULL) {
cout << "ERROR: NO FILE NAME FOUND" << endl;
return -1;
}
if (strcmp(argv[1], "random") != 0) {
cout << argv[1] << endl;
ifstream fp;
fp.open(argv[1]);
if (!fp.is_open()) {
cout << "ERROR: NO FILE FOUND" << endl;
return -1;
}
while (!fp.eof()) {
fp >> x;
cout << x << " ";
fp >> y;
cout << y << endl;
point pnt(x,y);
origin.push_back(pnt);
cout << "Point children" << endl << origin[i].place('x') << " " << origin[i].place('y') << endl;
i++; //FIXME: DELETE THIS AFTER TESTING
}
edgeList z(origin[0], origin[1]);
}
return 0;
}
What am I doing wrong here?
You're not initialising any of your class edgeList's members.
Well, you are, but by default. Doing that requires a default constructor, which point doesn't have. Hence the error.
Those three lines in the edgeList constructor are assignments after-the-fact:
edgeList(const point& origin, const point& terminal) {
this->origin = origin;
this->terminal = terminal;
this->weight = findWeight(origin, terminal);
}
Here's what you're supposed to do, to initialise members:
edgeList(const point& origin, const point& terminal)
: origin(origin)
, terminal(terminal)
, weight(findWeight(origin, terminal))
{}
Currently your code is more like:
edgeList(const point& origin, const point& terminal)
: origin()
, terminal()
, weight()
{
this->origin = origin;
this->terminal = terminal;
this->weight = findWeight(origin, terminal);
}
If your C++ book doesn't explain this, you need a better one!

Can i use nested loops with vectors in cpp?

i have a cpp problem and i don't know whats wrong.. maybe you can help me :).
I'm trying to implement a data structure for a graph. In this graph i will connect some nodes, which have a small euclidean distance, but at the second iteration, my iterator will point to 0x0. This case appears only, if i give the distance of those two nodes to std::cout. Here is my code:
for(vector<Node*>::iterator n1 = g->getNodes().begin(); n1 != g->getNodes().end(); ++n1)
{
for(vector<Node*>::iterator n2 = g->getNodes().begin(); n2 != g->getNodes().end(); ++n2)
{
if(*n2 == 0)
{
// This will be entered after the first iteration of n2.
cout << "n2 null" << endl;
continue;
}
double distance = (*n1)->getDistance(*n2); // just euclidean distance
if(distance <= minDistance)
{
// This works fine:
cout << "(" << *n1 << "," << *n2 << ") << endl;
// This brings me a "Segmentation fault"
cout << "(" << *n1 << " , " << *n2 << ") -> " << distance << endl;
}
}
}
Is this owed by the nested loops? Can any body tell me my fault? Thanks a lot!
EDIT: Here is some more code:
node.h
#ifndef NODE_H_
#define NODE_H_
#include <vector>
#include <iostream>
#include <limits>
#include <math.h>
using namespace std;
class Node
{
private:
int x, y, z;
public:
Node(int x, int y, int z) : x(x), y(y), z(z)
{
}
inline int getX() { return x; }
inline int getY() { return y; }
inline int getZ() { return z; }
inline double getDistance(Node* other)
{
return sqrt(pow(x-other->getX(), 2) + pow(y-other->getY(), 2) + pow(z-other->getZ(), 2));
}
};
#endif
graph.h
#ifndef GRAPH_H_
#define GRAPH_H_
#include <vector>
#include "node.h"
using namespace std;
class Graph
{
private:
vector<Node*> nodes;
public:
~Graph()
{
while(!nodes.empty())
{
delete nodes.back(), nodes.pop_back();
}
}
inline vector<Node*> getNodes() { return nodes; }
inline int getCountNodes() { return nodes.size(); }
bool createNode(int x, int y, int z)
{
nodes.push_back(new Node(x, y, z));
return true;
};
#endif
main.cc
#include <iostream>
#include <vector>
#include <algorithm>
#include <math.h>
#include "model/graph.h"
using namespace std;
int main()
{
Graph *g = new Graph();
int nodeDistance = 100;
for(int z = 0; z <= 300; z += nodeDistance)
{
for(int x = 0; x <= 500; x += nodeDistance)
{
for(int y = 0; y <= 300; y += nodeDistance)
{
g->createNode(x, y, z);
}
}
}
for(vector<Node*>::iterator n1 = g->getNodes().begin(); n1 != g->getNodes().end(); ++n1)
{
for(vector<Node*>::iterator n2 = g->getNodes().begin(); n2 != g->getNodes().end(); ++n2)
{
if(*n2 == 0)
{
// This will be entered after the first iteration of n2.
cout << "n2 null" << endl;
continue;
}
double distance = (*n1)->getDistance(*n2); // just euclidean distance
if(distance <= nodeDistance)
{
// This works fine:
cout << "(" << *n1 << "," << *n2 << ") << endl;
// This brings me a "Segmentation fault"
cout << "(" << *n1 << " , " << *n2 << ") -> " << distance << endl;
}
}
}
delete g;
return 0;
}
One major issue is that your getNodes function returns a copy of a vector, not the original vector. Therefore your iterators you use in the loops are not iterating over the same vector.
Instead, the iterators you're using in the nested loops are iterating over 4 different (but equivalent) vectors instead of the actual vector from the object in question.
There is nothing wrong in returning a copy of a vector in general. However when you do this, you have to make sure you call such a function if you really want a copy, and not the same vector. Using the getNodes function as you used it is not a valid usage in terms of what you are trying to accomplish.
The error is here:
inline vector<Node*> getNodes() { return nodes; }
The fix:
inline vector<Node*>& getNodes() { return nodes; }
The latter ensures that a reference to the actual vector in question is returned, not a copy of the actual vector. You can add an additional function that returns the vector as a copy if you want to still have the functionality available.

c++ error: object of abstract class type "..." is not allowed

I want to use polymorphism in my program but don't know why when I create
virtual void setVertices()=0;
in class CFigure i get an error
C2259: 'CRectangle': cannot instantiate abstract class (line 63 and 74)
IntelliSense: object of abstract class type "CRectangle" is not allowed:
pure virtual function "CFigure:setVertices" has no overrider (line 63 and 74)
I want also to declare:
virtual void setVertices(CFigure& fig) = 0;
I don't know at all that if I can write CFigure& fig cuz CRectangle i have:
void setVertices(CRectangle& fig)
and those two methods have different parameters.
Can someone can tell me how to help me to explain those errors and tell me how to fix my program? Code:
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
class Point2D{
int x, y;
public:
void setX(int X){ x = X; }
void setY(int Y){ y = Y; }
int getX(){ return x; }
int getY(){ return y; }
};
class CFigure :public Point2D
{
protected:
Point2D Vert[4];
public:
CFigure(){}
//virtual void setVertices(CFigure& fig) = 0;
virtual void setVertices()=0;// if I comment this line all works good
};
class CRectangle : public CFigure
{
public:
CRectangle(){}
void setVertices(CRectangle& fig)
{
//CRectangle fig;
int x1, y1, a;
cout << "Give x1, y1" << endl;
cin >> x1 >> y1;
cout << "Give a" << endl;
cin >> a;
fig.Vert[0].setX(x1);
fig.Vert[0].setY(y1);
fig.Vert[1].setX(x1 + a);
fig.Vert[1].setY(y1);
fig.Vert[2].setX(x1);
fig.Vert[2].setY(y1 + a);
fig.Vert[3].setX(x1 + a);
fig.Vert[3].setY(y1 + a);
}
void showPoints()
{
CRectangle f;
setVertices(f);
for (int i = 0; i < 4; i++)
{
cout << "P" << i << "( " << f.Vert[i].getX() << " " << f.Vert[i].getY() << " ) " << endl;
}
}
};
int main()
{
CRectangle ag;
ag.showPoints();
return 0;
}
CFigure declares setVertices() as:
virtual void setVertices()=0;
But CRectangle declares setVertices() as:
void setVertices(CRectangle& fig)
The additional parameter makes it so CRectangle::setVertices() is not overriding CFigure::setVertices(). It is overloading it instead. That is why the compiler is complaining that CRectangle is an abstract class - it really is. When you override a virtual method, the signature of the overriding method must exactly match the signature of the method that is being overridden, eg:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
class Point2D
{
int x, y;
public:
void setX(int X){ x = X; }
void setY(int Y){ y = Y; }
int getX(){ return x; }
int getY(){ return y; }
};
class CFigure : public Point2D
{
protected:
Point2D Vert[4];
public:
CFigure() {}
virtual void setVertices()=0;
};
class CRectangle : public CFigure
{
public:
CRectangle() {}
void setVertices()
{
int x1, y1, a;
cout << "Give x1, y1" << endl;
cin >> x1 >> y1;
cout << "Give a" << endl;
cin >> a;
Vert[0].setX(x1);
Vert[0].setY(y1);
Vert[1].setX(x1 + a);
Vert[1].setY(y1);
Vert[2].setX(x1);
Vert[2].setY(y1 + a);
Vert[3].setX(x1 + a);
Vert[3].setY(y1 + a);
}
void showPoints()
{
setVertices();
for (int i = 0; i < 4; i++)
{
cout << "P" << i << "( " << Vert[i].getX() << " " << Vert[i].getY() << " ) " << endl;
}
}
};
int main()
{
CRectangle ag;
ag.showPoints();
return 0;
}