С++: подключение члена класса к его определению

Я новичок в С++, у меня больше опыта в OCaml и Python. Я хочу научиться С++, создав программу, играющую "Morpion Solitaire". Мои начинания немного сложны.

В следующем коде:

typedef enum {NORTH, NORTHEAST, EAST, SOUTHEAST} direction;
char deltax[4] = { 0, 1, 1, 1};
char deltay[4] = { 1, 1, 0, -1};
class Coords {
 private:
 char x,y;
 public:
 Coords(char xx,char yy){
 x = xx;
 y = yy;
 };
 char get_x() const { return x;}
 char get_y() const { return y;}
};
class Line {
 private:
 Coords orig;
 direction dir;
 Coords newcross;
 public:
 Line(char x1, char y1, direction d, char x2, char y2) {
 orig = Coords(x1,y1);
 dir = d;
 newcross = Coords(x2,y2);
 };
 Coords nthpoint(char n) {
 char x,y;
 x = orig.get_x() + n*deltax[dir];
 y = orig.get_y() + n*deltay[dir];
 return Coords(x,y);
 };
};

компилятор говорит мне следующее:

nico@gaston:~/Travail/Cplusplus/morpion++$ g++ -c morpion.cc 
morpion.cc: In constructor ‘Line::Line(char, char, direction, char, char)’:
morpion.cc:29:57: error: no matching function for call to ‘Coords::Coords()’
 Line(char x1, char y1, direction d, char x2, char y2) {
 ^
morpion.cc:29:57: note: candidates are:
morpion.cc:11:3: note: Coords::Coords(char, char)
 Coords(char xx,char yy){
 ^
morpion.cc:11:3: note: candidate expects 2 arguments, 0 provided
morpion.cc:6:7: note: Coords::Coords(const Coords&)

Я не понимаю сообщение. Я дал 2 аргумента конструктора для класса Coords, но компилятор продолжает говорить мне, что orig = Coords(x1,y1) вызывает конструктор с 0 аргументами.

Что я пропустил?

Примечание: я изначально помещал объявления Coords и Line в разные файлы и думал, что не использовал правильный #include, но все в одном файле не решило проблему...

3 ответа

Line(char x1, char y1, direction d, char x2, char y2)
 : orig(x1,y1), dir(d), newcross(x2, y2) {}

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


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

Line(char x1, char y1, direction d, char x2, char y2): orig(), dir(), newcross() {
 orig = Coords(x1,y1); // this is assignment not construction
 dir = d; // this is assignment not construction
 newcross = Coords(x2,y2); // this is assignment not construction
};

Это не проблема для dir, поскольку она может быть неявно построена, но Coords не так orig() и newcross() не работает.

Чтобы исправить это, вам нужно использовать список инициализации члена и иметь конструктор типа

Line(char x1, char y1, direction d, char x2, char y2) : orig(x1, y1), newcross(x2, y2), dir(d) {}


TL; DR: исправление:

Line(char x1, char y1, direction d, char x2, char y2) :
 orig(x1, y1), newcross(x2, y2), dir(d)
{
};

Конструктор класса Line должен вызвать конструкторы всех членов этого класса и делает это до выполнения тела конструктора. То есть член orig должен быть построен до строки

orig = Coords(x1,y1);

выполнение. По умолчанию вызывается конструктор по умолчанию, но в вашем случае класс Coords не имеет конструктора по умолчанию. Когда мы пишем orig(x1, y1), мы переопределяем значение по умолчанию, а конструктор Coords(x1, y1) вызывается для построения orig.

licensed under cc by-sa 3.0 with attribution.