简体   繁体   中英

No default constructor exists for the class

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

  1. to use in-class initializers
  2. to use member initialization instead of setting in the constructor body
  3. 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{};
};

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM