I have defined a point class using dev c++. then I tried to overload cout for this class.
while not using it i get no error. but when i use it in main it gives me this error:
[Linker error] C:\Users\Mohammad\Desktop\AP-New folder\point/main.cpp:12: undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, Point const&)'
//point.h
class Point{
private:
double x;
double y;
double z;
public:
//constructors:
Point()
{
x=0;
y=0;
z=0;
}
Point(double xx,double yy,double zz){x=xx; y=yy; z=zz;}
//get:
double get_x(){return x;}
double get_y(){return y;}
double get_z(){return z;}
//set:
void set_point(double xx, double yy, double zz){x=xx; y=yy; z=zz;}
friend ostream &operator<<(ostream&,Point&);
};
//point.cpp
ostream &operator<<(ostream &out,Point &p){
out<<"("<<p.x<<", "<<p.y<<", "<<p.z<<")\n";
return out;
}
//main.cpp
#include <iostream>
#include "point.h"
using namespace std;
int main(){
Point O;
cout<<"O"<<O;
cin.get();
return 0;
}
This is because you did not make your Point a const when declaring and defining your operator. Change your declaration as follows:
friend ostream &operator<<(ostream&, const Point&);
Also add const in the definition:
ostream &operator<<(ostream &out, const Point &p){
out<<"("<<p.x<<", "<<p.y<<", "<<p.z<<")\n";
return out;
}
Note that the code that you posted does not require const-ness of the Point&. Some other code made your compiler or IDE believe that an operator with a const is referenced. For example, using the operator like this would require a const
cout << Point(1.2, 3.4, 5.6) << endl;
(demo)
Since the snippet above creates a temporary object, passing a reference to it as a non-const is prohibited by the C++ standard.
Not directly related to this issue, but you may want to mark the three getters for individual coordinates const as well:
double get_x() const {return x;}
double get_y() const {return y;}
double get_z() const {return z;}
This would let you access coordinates with getters on objects marked const.
Related
Having trouble with overloading operator<. I am trying to overload the operator< so that I can sort my Line2D object based on pt1's x. But I am having trouble figuring out how to declare the function.
I am getting the error:
object has type qualifiers that are not compatible with the member function "Point2D::getX".
What I have tried: removing const, putting Point2D &l2dobj instead.
class Line2D
{
private:
Point2D pt1;
Point2D pt2;
public:
bool operator<( const Line2D &l2dobj)
{
return (pt1.getX() < l2dobj.pt1.getX());
}
}
class Point2D
{
protected:
int x;
int y;
public:
int getX();
int getY();
}
Point2D::getX doesn't accept const instance, you cannot apply it on l2dobj while it is a const reference, change getX (and a priori getY) to :
class Point2D
{
protected:
int x;
int y;
public:
int getX() const;
int getY() const;
};
As a general way declare the methods const the more you can, and same for their parameters
I am stuck with regards to the 2 non-member, 2 non-friend multiplication and the addition of the operator overloading functions. I am unsure of how to do it. Could someone please assist in helping me to resolve this? Refer to my codes below. Thank you in advance!
Compiler output:
Point.cpp:208:19: error: passing ‘const CS170::Point’ as ‘this’ argument discards qualifiers [-fpermissive]
return other + value;
^~~~~
Point.cpp: In function ‘CS170::Point CS170::
operator*(double, const CS170::Point&)’:
Point.cpp:215:10: error: ‘double CS170::Point::x’ is private within this context
result.x = value * x;
^
Point.cpp:215:22: error: ‘x’ was not declared in this scope
result.x = value * x;
^
Point.cpp:216:10: error: ‘double CS170::Point::y’ is private within this context
result.y = value * y;
^
Point.cpp:216:23: error: ‘y’ was not declared in this scope
result.y = value * y;
Point.h
#include <iostream> // istream, ostream
namespace CS1100
{
class Point
{
public:
// Point(double X, double Y); // Constructors (2)
explicit Point(double x, double y);
Point();
Point operator+(const Point& other)const ;
Point& operator+(double value);
Point operator*(double value) ;
Point operator%(double value);
Point operator-(const Point& other)const ;
Point operator-(double value);
Point operator^(const Point& other);
Point operator+=(double value);
Point& operator+=(const Point& other) ;
Point& operator++();
Point operator++(int);
Point& operator--();
Point operator--(int);
Point& operator-();
// Overloaded operators (14 member functions)
friend std::ostream &operator<<( std::ostream &output, const Point &point );
friend std::istream &operator>>( std::istream &input, Point &point );
// Overloaded operators (2 friend functions)
private:
double x; // The x-coordinate of a Point
double y; // The y-coordinate of a Point
// Helper functions
double DegreesToRadians(double degrees) const;
double RadiansToDegrees(double radians) const;
};
// Point& Add(const Point& other); // Overloaded operators (2 non-member, non-friend functions)
// Point& Multiply(const Point& other);
Point operator+( double value, const Point& other );
Point operator-( double value, const Point& other );
My source code:
///////////////////////////////////////////////////////////////////////////////
// 2 non-members, non-friends (operators)
double operator+( double value, const Point& other )
{
return other + value;
}
double operator*( double value, const Point& other )
{
Point result;
result.x = value * x;
result.y = value * y;
return result;
}
As far as I understand the discussion to the question, the problem is not really the operators themselves, but the number of allowed member functions being limited – and you already have exceeded this limit.
However, you have quite a number of functions that don't need to be members, for instance:
class Point
{
public:
Point operator+(const Point& other) const
{
return Point(x + other.x, y + other.y);
}
};
Make free functions from all these:
class Point { /*...*/ };
Point operator+(Point const& l, Point const& r)
{
return Point(l.getX() + r.getX(), l.getY() + r.getY());
}
Having moved out all these operators like the one shown above, you get away far enough from the limit so that you can introduce the needed getters:
class Point
{
public:
double getX() { return x; };
double getY() { return y; };
};
If you are willing to rename the member variables, e. g. by adding a prefix, you can follow another pattern:
class Point
{
double m_x, m_y;
public:
double x() { return m_x; };
double y() { return m_y; };
void x(double v) { m_x = v; }; // the corresponding setter
// (for illustration, you might not need it)
};
This latter pattern is quite common, too. Advantage is being shorter for skipping the explicit get or set prefix, disadvantage is exactly losing this explicitness... Decide you, which one you prefer. More important than personal preference is consistency, though, so if there's e. g. a company's convention or common practice, follow that one...
Some of your operators will need to remain members, though, these are all those that modify the current object:
class Point
{
public:
Point& operator+=(const Point& other) /* const */ // NEEDS to be non-const
{
x += other.x;
y += other.y;
return *this; // <- very good hint to spot the ones needing to stay members
}
};
If you have a public copy constructor, you can re-use the operator+= for defining the operator+:
class Point
{
public:
Point(Point const& other) : Point(other.x, other.y) { }
};
Point operator+(Point const& x, Point const& y)
{
Point r(x); // or Point(x.x(), x.y()), if you lack such constructor)
r += y;
return r;
}
Actually, you can even spare the explicit copy by accepting one of the parameters by value:
Point operator+(Point x, Point const& y)
// ^ no reference
{
return x += y;
}
The latter rather for illustration, I'd prefer the two references in given case to keep the symmetry of the interface...
The code below cannot be compiled. However, when I remove "const" from Point& of the friend function, this code turns to be compiled. Could anyone explain the reason why?
class Point
{
public:
Point(double x, double y);
Point operator+(const double& add);
friend Point operator+(const double& add, const Point& p){return p+add;}
private:
double px, py;
};
Point::Point(double x, double y): px(x), py(y){}
Point Point::operator+(const double& add){
return(Point(px+add, py+add));
}
int main(){}
The operator+ is not marked as a const, yet is tried to be called through a const reference.
Constant pointers and references are only allowed to call member functions that are marked constant (since the compiler definitely knows that those functions are ensured not to modify internal state).
class Point2D
{
protected:
int x;
int y;
public:
Point2D () {x=0; y=0;}
Point2D (int a, int b) {x=a; y=b;}
void setX (int);
void setY (int);
int getX ();
int getY ();
};
class Line2D
{
friend ostream& operator<< (ostream&, const Line2D&);
private:
Point2D pt1;
Point2D pt2;
double length;
public:
Line2D () {pt1 = Point2D(); pt2 = Point2D();}
Line2D (Point2D ptA, Point2D ptB) {pt1=ptA; pt2=ptB;}
void setPt1 (Point2D);
void setPt2 (Point2D);
Point2D getPt1 ();
Point2D getPt2 ();
};
ostream& operator<< (ostream &out, const Line2D &l)
{
//out << l.length << endl; //Reading length works perfectly
out << l.getPt1().getX() << endl; //But how to read x from pt1 ?
return out;
}
When I run these codes, I get error saying:
no matching function for call to Line2D::getPt1() const and
note: candidates are: Point2D Line2D::getPt1() <near match>.
If I am only trying to display length by overloading << operator , it works perfectly. But when I try to printx and y of Class::Point2D, I get error.
So what should be the proper way to print out x and y ?
Your operator (rightly) takes a const reference. So any methods called via that reference must be const. For example,
Point2D getPt1 () const;
^^^^^
You should also make the Point2D class getters const.
I have a demo program for understanding of friend function. I am stuck up with errors related to forward declaration stuff, I guess.
I have a point class which has x & y co-ordinates. The line class has two objects of point class. Now I have a function in line class which will calculate the slope of the line.
This is my program:
#include <iostream>
using namespace std;
class point
{
int x,y;
public:
point(int,int);
point();
friend float line::slope();
};
point::point(int a, int b)
{
x=a;
y=b;
}
point::point()
{
}
class line
{
point p1,p2;
public:
line(point,point);
float slope();
};
line::line(point p1, point p2)
{
this->p1=p1;
this->p2=p2;
}
float line::slope()
{
float s;
s=((float)p2.y-p1.y)/(p2.x-p1.x);
return s;
}
int main()
{
float sl;
point obj(5,10);
point obj1(4,8);
line obj3(obj,obj1);
sl=obj3.slope();
cout<<"\n slope:"<<sl;
return 0;
}
It is giving me compiler errors with respect to forward declarations due to the following:
When I try to define my line class first, it does not know about the point class. Even if I forward declare the point class, that wont suffice coz to create objects of the point class, the compiler should know the size of the point class and hence the whole class itself. Understood it through explanation in this answer: https://stackoverflow.com/a/5543788
If I define the point class first, it needs to know the friend function slope and hence the class line.
So I tried to provide the forward declaration for the line class and the slope function like this before defining the point class:
class line;
float line::slope();
class point
{
int x,y;
public:
point(int,int);
point();
friend float line::slope();
};
Now this gives me the following errors:
friend1.cpp:5: error: invalid use of incomplete type ‘struct line’
friend1.cpp:4: error: forward declaration of ‘struct line’
friend1.cpp:13: error: invalid use of incomplete type ‘struct line’
friend1.cpp:4: error: forward declaration of ‘struct line’
friend1.cpp: In member function ‘float line::slope()’:
friend1.cpp:9: error: ‘int point::y’ is private
friend1.cpp:43: error: within this context
friend1.cpp:9: error: ‘int point::y’ is private
friend1.cpp:43: error: within this context
friend1.cpp:9: error: ‘int point::x’ is private
friend1.cpp:43: error: within this context
friend1.cpp:9: error: ‘int point::x’ is private
friend1.cpp:43: error: within this context
.3. Next I tried to separate out the point class in point.h and point.cpp and line class in line.h and line.cpp. But still here there is a dependency on each other.
Though this should be possible theoretically, I cannot figure it out how to get it working.
Looking out for answers.
Thanks,
Raj
PS: This program is an effort to demonstrate the usage of friend functions alone. Where friend functions are of two types, this is an effort to deal with the second of this kind:
Friend functions which are independent.
Friend functions which are members of another class.
So, usage of friend classes are ruled out in this case.
Add line as a friend, not just a method:
friend class line;
Other remarks:
separate declarations from the implementations in header and implementation files.
prefer full qualification over using directives (i.e. remove using namespace std; and use std::cout instead.
prefer pass-by-reference for complex types - change line(point,point); to line(const point&, const point&);
EDIT For educational purposes - You can't declare that specific function as friend as the code is now because there's no full definition of the line class. Ergo, the following is the only approach:
class point;
class line
{
point *p1,*p2;
public:
line(point,point);
float slope();
};
class point
{
int x,y;
public:
point(int,int);
point();
friend float line::slope();
};
You forward-declare point and change the point members in line to point* (because point isn't a complete type yet). In point you now have the full definition of the line class, so you can declare the method as friend.
EDIT 2: For this particular scenario, it's not possible using point objects inside line because you'd need the full type. But line would also have to be fully defined in order to declare its member as friend.
Just make Line a friend of Point
class point
{
friend class line;
...
};
There's very little purpose in declaring individual methods as friends.
You can create a helper functor to calculate slope. This allows you to make the method of the functor a friend of the point without involving line.
class point;
class line;
struct slope {
float operator () (const point &, const point &) const;
float operator () (const line &) const;
};
class point {
int x,y;
public:
point(int a,int b) : x(a), y(b) {}
point() {}
friend float slope::operator ()(const point &, const point &) const;
};
class line {
point p1,p2;
public:
line(point a,point b) : p1(a), p2(b) {}
float slope() { return ::slope()(*this); }
friend float slope::operator ()(const line &) const;
};
With the implementations:
float slope::operator () (const point &p1, const point &p2) const {
float s;
s=((float)p2.y-p1.y)/(p2.x-p1.x);
return s;
}
float slope::operator () (const line &l) const {
return (*this)(l.p1, l.p2);
}
Under normal circumstances, I would avoid using friend here at all.
Prefer to add a function to point:
float slope_to(const point& other)
{// Not checked, just translated from your implementation
return ((float)other.y-y)/(other.x-x);
}
And implement:
float line::slope()
{
return p1.slope_to(p2);
}
This way line doesn't care about point's implementation and will not need to be changed when you implement 3D points.
Here is a demonstration of a friend of a free function (1.):
#include <iostream>
class point
{
int x, y;
public:
point(int, int);
friend std::ostream& operator <<(std::ostream& os, const point& p);
};
std::ostream& operator <<(std::ostream& os, const point& p)
{
return os << '(' << p.x << ", " << p.y << ')';
}
point::point(int a, int b)
:x(a)
,y(b)
{
}
int main()
{
point obj(5, 10);
std::cout << "\n point " << obj;
}
Here is an example building on your own code to have a friend of a member function (2.).
#include <iostream>
#include <memory>
using namespace std;
class point;
class line
{
std::auto_ptr<point> p1, p2;
public:
line(point&, point&);
float slope();
};
class point
{
int x, y;
public:
point(int, int);
friend float line::slope();
};
point::point(int a, int b)
:x(a)
,y(b)
{
}
line::line(point& p1, point& p2)
:p1(new point(p1))
,p2(new point(p2))
{
}
float line::slope()
{
return ((float)p2->y - p1->y) / (p2->x - p1->x);
}
int main()
{
point obj(5, 10);
point obj1(4, 8);
line obj3(obj, obj1);
cout << "\n slope:" << obj3.slope();
}
In order to reference point from within line, I use (auto_) pointers and references, since the class is declared at that point but not defined. line::slope() is declared in time for me to reference it as a friend of point. This circular dependency is a terrible code smell and should be avoided.
you refer to the line class in friend float line::slope(); before the class is defined.
just add the line class line; before the definition of the Point class
also change friend float line::slope(); to friend class line;