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 Point
s) then you don't automatically get the default constructor, you need to add it yourself.
I suggest changing your classes
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{};
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.