Для класса не существует конструктора по умолчанию - PullRequest
1 голос
/ 03 мая 2020

Я знаю, что этот вопрос уже задавался, но я не мог понять это. У меня есть два класса Point и Line, и 2 Point являются членами Line. Однако в конструкторе Line я получаю сообщение об ошибке «для класса не существует конструктора по умолчанию». Как я могу решить эту проблему?

#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;
    }


};

Ответы [ 5 ]

1 голос
/ 03 мая 2020

Причина вашей ошибки в том, что этот код вызывает конструктор Point по умолчанию (который не существует)

Line(const Point& p1, const Point& p2) {
    this->point1 = p1;
    this->point2 = p2;
}

, вместо этого вы должны написать его так:

Line(const Point& p1, const Point& p2) : point1(p1), point2(p2) {
}

Ваша версия вызывает конструктор Point по умолчанию, а затем присваивает значения точек. Моя версия инициализирует точек, вызывая конструктор копирования Point

0 голосов
/ 03 мая 2020

Проблема в том, что у вас нет конструктора по умолчанию для этого класса, и поэтому, когда вы создаете точки, вы не знаете, какие значения будут принимать их переменные. Самый простой и быстрый способ решения - дать конструктору значения по умолчанию, когда он не получает параметры

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;
}

};

0 голосов
/ 03 мая 2020

Конструктор по умолчанию - конструктор без параметров. Если у вас есть предоставленный пользователем конструктор, принимающий параметры (например, ваш конструктор Line, принимающий два Point с), тогда вы не получите автоматически конструктор по умолчанию, вам нужно добавить его самостоятельно.

Я предлагаю изменить ваши классы

  1. для использования инициализаторов в классе
  2. для использования инициализации члена вместо установки в теле конструктора
  3. по умолчанию с конструктором по умолчанию (который требует шага 1)

Вы можете сравнить IsoCppCoreguidelines для более подробного объяснения этих изменений.


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{};
};
0 голосов
/ 03 мая 2020

Основная причина, по которой вы получаете эту ошибку. Это потому, что конструктор Line не знает, как инициализировать point1 и point2 до ваших операторов присваивания в конструкторе. Вот для чего нужны списки инициализации конструктора. Обычно лучше инициализировать начальный элемент в списке инициализации конструктора, а не в теле конструктора. Без списка инициализации конструктора point1 и point2 создаются с конструктором по умолчанию (ошибка, потому что он отсутствует), а затем немедленно обновляются дополнительным кодом в теле конструктора. Вы можете избежать необходимости использования конструктора по умолчанию в Point, задав Line конструктор, заданный следующим образом:

Line(const Point& p1, const Point& p2) : point1(p1), point2(p2)
{}

Это разрешит ошибку вашего компилятора. Кроме того, все еще неплохо иметь конструктор по умолчанию для Point. Это тип класса, где часто бывает полезно иметь такой конструктор. И через некоторое время вам может понадобиться коллекция Point экземпляров, и компилятор снова будет жаловаться без этого. В этом отношении ответ MakeCAT является правильным.

В сторону : Ваша функция Distance передает Point параметры по значению. Это означает, что компилятору необходимо создавать 3 новых экземпляра Point каждый раз, когда вызывается Distance. Измените свою подпись функции для Distance следующим образом. Если это не сделает компилятор счастливым, он, по крайней мере, сгенерирует более эффективный код.

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;
    }
0 голосов
/ 03 мая 2020

В сообщении об ошибке указано «нет конструктора по умолчанию», поэтому вы должны добавить единицы.

class Line {
public:
    Line() {} // add this

    Line(const Point& p1, const Point& p2) {
class Point {
public:
    Point() {} // add this
    Point(double a, double b) {

или единицы с инициализацией (более безопасные):

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) {

или конструкторы с аргументами по умолчанию:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...