No default constructor exists for the class - c++

I know this question has already been ask, but I couldn't figure it out.
I have two classes Point and Line, and 2 Points are members of Line. However in the Line constructor I get "no default constructor exists for the class" error. How can I fix this problem?
#include <cstdlib>
#include <cmath>
#include "PointClass.h"
using namespace std;
class Line {
public:
Line(const Point& p1, const Point& p2) {
this->point1 = p1;
this->point2 = p2;
}
Point point1;
Point point2;
static double Distance(Point p1, Point p2, Point p3) {
double distance = (abs((p1.y - p2.y) * p3.x - (p2.x - p1.x) * p3.y + p2.x * p1.y - p2.x * p1.x) / (sqrt(pow((p2.y - p1.y), 2.0) + pow((p2.x - p1.x), 2.0))));
return distance;
}
};
class Point {
public:
Point(double a, double b) {
this->setCoord(a, b);
}
double x;
double y;
void setCoord(double a, double b)
{
this->x = a;
this->y = b;
}
};

The reason for you error, is that this code calls the Point default constructor (which doesn't exist)
Line(const Point& p1, const Point& p2) {
this->point1 = p1;
this->point2 = p2;
}
instead you should write it like this
Line(const Point& p1, const Point& p2) : point1(p1), point2(p2) {
}
Your version calls the Point default constructor and then assigns the point values. My version initialises the points by calling the Point copy constructor

The error message says "no default constructor", so you should add ones.
class Line {
public:
Line() {} // add this
Line(const Point& p1, const Point& p2) {
class Point {
public:
Point() {} // add this
Point(double a, double b) {
or ones with initialization (safer):
class Line {
public:
Line() : point1(), point2() {} // add this
Line(const Point& p1, const Point& p2) {
class Point {
public:
Point() : x(0), y(0) {} // add this
Point(double a, double b) {
or constructors with default arguments:

The core reason you are getting that error. Is because Line constructor doesn't know how to initialize point1 and point2 prior to your assignment statements in the constructor. That's what constructor initialization lists are for. It's usually better to do initial member initialization in the constructor initialization list instead of in the constructor body. Without a constructor initialization list, point1 and point2 get constructed with the default constructor (error because it's missing) and then immediate updated with additional code in constructor body. You can avoid the need for a default constructor on Point by having Line constructor defined as follows:
Line(const Point& p1, const Point& p2) : point1(p1), point2(p2)
{}
That will resolve your compiler error. Further, it's still not a bad idea to have a default constructor for Point. It's the type of class where it's often useful to have such a constructor. And some point later, you might need to have a collection of Point instances and the compiler will complain again without it. MakeCAT's answer is correct in that regards.
Aside: Your Distance function is passing Point parameters by value. This means the compiler needs to construct 3 new instances of Point each time Distance is invoked. Change your function signature for Distance as follows. If this doesn't make the compiler happy, it will at the very least, generate more efficient code.
static double Distance(const Point& p1, const& Point p2, const& Point p3) {
double distance = (abs((p1.y - p2.y) * p3.x - (p2.x - p1.x) * p3.y + p2.x * p1.y - p2.x * p1.x) / (sqrt(pow((p2.y - p1.y), 2.0) + pow((p2.x - p1.x), 2.0))));
return distance;
}

The problem is that you don't have a default constructor for that class and therefore when you create the points you don't know what values their variables will take.
The easiest and fastest way of solutions is to give default values to the constructor when it does not receive parameters
class Point {
public:
//only modification here
Point(double a = 0, double b = 0) {
this->setCoord(a, b);
}
double x;
double y;
void setCoord(double a, double b)
{
this->x = a;
this->y = b;
}
};

The default constructor is the constructor without parameters. If you have a user provided constructor taking parameters (like your Line constructor taking two Points) then you don't automatically get the default constructor, you need to add it yourself.
I suggest changing your classes
to use in-class initializers
to use member initialization instead of setting in the constructor body
defaulting the default constructor (which requires step 1)
You can compare the IsoCppCoreguidelines for a more detailed explanation on these changes.
class Point {
public:
Point() = default;
Point(double a, double b) : x{a}, y{b} {}
double x{};
double y{};
};
class Line {
public:
Line() = default;
Line(const Point& p1, const Point& p2) : point1{p1}, point2{p2} {}
Point point1{};
Point point2{};
};

Related

how to use +operator proper in object combinining?

class Point {
private:
float xcord;
float ycord; }
class Line{
friend class Nonlinear;
protected:
float dist;
Point *p1,*p2;
virtual const Line& operator+(const Line& l) const;
for virtual operator+ how can i update the new p1 and p2 values of newly created object?
i can update the dist value by using
Line *l1=(Line*)&l
l1->dist=dist+l.dist
but i didnt understand why i am getting stuck on combining Points.

Operator overloading functions

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...

How to overload an operator for integer, float and double data types simultaneously in C++

I'm creating a 2D coordinate class (named “Point”) to help me learn C++. I want to be able to perform basic arithmetic operations (+, -, *, / ...) on Point class objects (e.g. Point_a + Point_b). However, I also want to be able to perform such operations between Points and other variable types (int/float/double).
This can be done using operator/function overloading. It can be seen from my code below (addition only) that I must, as far as I am aware, include two additional functions for each additional variable type, one for the “Point + int/float/double” form and one for the “int/float/double + Point” form.
#include <iostream>
using namespace std;
class Point
{
private:
double x, y;
public:
Point(double x_in, double y_in){
setX(x_in);
setY(y_in);
}
// Getters and Setters omitted for brevity
// --- Start of Addition Operator Overloads --- (Code Block A)
friend Point operator+(const Point &p1, const Point &p2); //Point + Point
friend Point operator+(const Point &p1, int val); //Point + Int
friend Point operator+(int val, const Point &p1); //Int + Point
friend Point operator+(const Point &p1, float val); //Point + Float
friend Point operator+(float val, const Point &p1); //Float + Point
friend Point operator+(const Point &p1, double val); //Point + Double
friend Point operator+(double val, const Point &p1); //Double + Point
// --- End of Addition Operator Overloads --- (Code Block A)
};
// --- Start of Addition Operator Overload Functions --- (Code Block B)
Point operator+(const Point &p1, const Point &p2){
return Point(p1.x + p2.x, p1.y + p2.y);
}
Point operator+(const Point &p1, int val){
return Point(p1.x + val, p1.y + val);
}
Point operator+(int val, const Point &p1){
return Point(p1.x + val, p1.y + val);
}
Point operator+(const Point &p1, float val){
return Point(p1.x + val, p1.y + val);
}
Point operator+(float val, const Point &p1){
return Point(p1.x + val, p1.y + val);
}
Point operator+(const Point &p1, double val){
return Point(p1.x + val, p1.y + val);
}
Point operator+(double val, const Point &p1){
return Point(p1.x + val, p1.y + val);
}
// --- End of Addition Operator Overload Functions --- (Code Block B)
int main()
{
Point point_a( 2.00, 20.00);
Point point_b( 0.50, 5.00);
Point point_c = point_a + point_b;
cout << "X = " << point_c.getX() << " and Y = " << point_c.getY() << endl;
return 0;
}
There seems to be a lot of repetition, particular between “Point + int/float/double” type functions. I was wondering if there is a way that this could be shorted a little. Say, rather than having individual versions for integer, float and double I could have one version which would handle all three. For example converting code blocks "A" and "B" into something like:
...
// --- Start of Addition Operator Overloads --- (Code Block A)
friend Point operator+(const Point &p1, const Point &p2); //Point + Point
friend Point operator+(const Point &p1, int||float||double val); //Point + Int/Float/Double
friend Point operator+(int||float||double val, const Point &p1); //Int/Float/Double + Point
// --- End of Addition Operator Overloads --- (Code Block A)
...
...
// --- Start of Addition Operator Overload Functions --- (Code Block B)
Point operator+(const Point &p1, const Point &p2){
return Point(p1.x + p2.x, p1.y + p2.y);
}
Point operator+(const Point &p1, int||float||double val){
return Point(p1.x + val, p1.y + val);
}
Point operator+(int||float||double val, const Point &p1){
return Point(p1.x + val, p1.y + val);
}
// --- End of Addition Operator Overload Functions --- (Code Block B)
...
The above code section is intended to be representational of the desired result rather than actually functional (e.g. int OR float OR double).
In short, is there any way that I can make "friend Point operator+(const Point &p1, int val);" and its corresponding function (in code block B) accept integer, float and double values, or do I need to have an individual one for each variable type?
Thank you for your time.
Other answers mention templates but in actual fact, all numeric types will automatically be promoted to doubles.
Therefore, you only need to provide operators in terms of Point and double.
#include <iostream>
using namespace std;
class Point
{
private:
double x, y;
public:
Point(double x_in, double y_in){
setX(x_in);
setY(y_in);
}
// Getters and Setters omitted for brevity
double getX() const { return x; }
double getY() const { return y; }
void setX(double v) { x = v; }
void setY(double v) { y = v; }
// unary ops
Point& operator+=(Point const& other)
{
x += other.x;
y += other.y;
return *this;
}
Point& operator+=(double v)
{
x += v;
y += v;
return *this;
}
// --- Start of Addition Operator Overloads --- (Code Block A)
friend Point operator+(Point p1, const Point &p2)
{
p1 += p2;
return p1;
}
friend Point operator+(Point p1, double val)
{
p1 += val;
return p1;
}
friend Point operator+(double val, Point p1)
{
p1 += val;
return p1;
}
// --- End of Addition Operator Overloads --- (Code Block A)
};
// --- End of Addition Operator Overload Functions --- (Code Block B)
int main()
{
Point point_a( 2.00, 20.00);
Point point_b( 0.50, 5.00);
Point point_c = point_a + point_b;
point_c += 10;
Point point_d = point_c + 10;
Point point_e = point_d + 10.1;
cout << "X = " << point_c.getX() << " and Y = " << point_c.getY() << endl;
return 0;
}
Such can be more generalized by using templates and specializing the exceptional case, instead of providing an overloaded version for each and every matching type:
class Point
{
public:
// ...
template<typename T>
friend Point operator+(const Point &p1, T p2);
};
template<typename T>
Point operator+(const Point &p1, T val){
static_assert(std::is_artithmetic<T>::value,"An arithmetic type is required");
return Point(p1.x + val, p1.y + val);
}
// Specialization for Point
template<>
Point operator+(const Point &p1, const Point& val){
return Point(p1.x + val, p1.y + val);
}
Separate solution than the template solution is to define constructors for the types you want to support, and have a single operator+ that works on Point types.
The compiler will implicitly call the proper constructor to convert the built-in type, before invoking operator+.
This simplifies the implementation, at the expense of wasted temp objects.
// Example program
#include <iostream>
#include <string>
class Point {
private:
double x, y;
public:
Point(int val) {
this->x = val;
this->y = val;
}
Point(double x, double y) {
this->x = x;
this->y = y;
}
friend Point operator+(const Point &p1, const Point &p2) {
return Point(p1.x + p2.x, p1.y + p2.y);
}
};
int main()
{
Point p(1,2);
Point q = p + 10;
Point v = 10 + p;
}
There is a stylistic argument about explicitly white-listing supported types via the constructors, and blacklisting via static_asserts.
You can absolutely do this using templates:
// inside the class
template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
friend Point operator+(const Point &p1, T val) {
// function definition
}
// Don't forget to define the function for T on the left hand side
This uses std::enable_if and std::is_arithmetic, to make this function only accept types that are "arithmetic types", basically integers and floats.
Point's operator+ implementations all converts its non-Point arguments to doubles before doing a + on elements.
The float and int overloads are nearly pointless. Just write the two double overloads.
Built-in conversion from int and float will then occur in the operator+ call.
If you really need int/float overloads and you know why and have tested that the double overload doesn't work, consider fixing the broken template conversion operator which is about the only way I can see this bbeing the case.
Failing that, cast to double explicitly.
Failing that, maybe write a template + that takes any T convertible to double, then converts and calls the above + for double. Then add a paragraph of documentation why you had to do something this stupid and complex instead of just overloading + with double. Then read that paragraph and change your mind and stick with + overloaded with double.

Is it possible to set a class object reference as a default parameter in c++ without const?

For example, this:
Class Point{
double x, y;
public:
Point();
bool testequal(const Point& p1, Point& p2 = Point()) const;
}
doesn't work. It gives me an error:
error: could not convert 'Point()' from Point to Point&
This works if I use it as,
bool testequal(const Point& p1, const Point& p2 = Point()) const;
or
bool testequal(const Point& p1, Point p2 = Point()) const;
But instead I want to use object p2 as a reference value whose data can be changed inside the implementation.
Edit:
Here is the complete program. Yes, it's trivial - I'd prefer it if you wouldn't assess the need for this code, but instead comment on whether it's possible to implement.
If not, could you please state why, and tell me what the right way to do it is. Is overloading the only option?
#ifndef __POINT_H__
#define __POINT_H__
Class Point{
double x, y;
public:
Point();
Point(double xx, double yy);
bool testequal(const Point& p1, Point& p2 = Point()) const;
// this declaration fails. alternative is to use const Point& p2 or Point p2.
// but it is vital that the default parameter should store some value in
// it which can be accessed at the function call location without returning it.
}
#include "Point.h"
Point::Point(): x(0), y(0) {}
Point::Point(double xx, double yy): x(xx), y(yy) {}
bool Point::testequal(const Point& p1, Point& p2){
if (this->x == p1.x && this->y == p1.y){
p2.x = this->x;
p2.y = this->y;
return true;
}
else
return false;
}
You may add an overload:
bool testequal(const Point& p1, Point& p2) const;
bool testequal(const Point& p1) const
{
Point dummy;
return testequal(p1, dummy);
}

C++ Operator overload: stl sort on vector of my custom class

I have a very basic class that is stored inside an STL Vector. I am trying to sort that vector, but am getting cryptic STL errors. Can someone assist?
// Point.h
class Point {
public:
Point() : x(0), y(0) {}
Point( float x0, float y0 ) : x(x0), y(y0) {}
float x;
float y;
};
// Point.cpp, updated const as per given answers
bool operator< (const Point &p1,const Point &p2)
{
return p1.x < p2.x || (p1.x==p2.x && p1.y< p2.y);
}
Again, this Point class is stored in a vector and is being sorted:
std::vector<Point> tmp=N->points;
std::sort(tmp.begin(),tmp.end());
Errors:
http://ideone.com/WIv0u
Can someone point me in the right direction? Thanks!
bool operator< (constPoint &p1,constPoint &p2 )