Учу C++ на примере проекта (игра в пешки, суть и смысл игры значения не имеют). Есть объект Pawns (это обертка игры).
class Pawns {
vector<Pawn> pawns;
char side;
void move(char side);
public:
Pawns(char side);
void start();
vector<Pawn> getPawns();
};
В функции main() он создается вот так:
Pawns game('w');
game.start();
Где Pawns::start() отдает команду Pawns::move(), которая в зависимости от цвета наших фигур выбирает, ожидать ход от противника или делать его самим. Окей, пусть мы играем белыми, игра только началась – значит, ходим мы. Для того, чтобы сделать ход, нужно проанализировать ситуацию на доске. Этим занимается объект Analysis:
class Analysis {
int deep; // max level
int level; // current level
Pawns field; // an instance of field
vector<Pawn> pawns; // an array of pawns
public:
Analysis(Pawns field, int deep);
map<int, int> choose();
int score();
int heuristic();
};
К чему я веду. У меня не работает конструктор. Вот в чем проблема: как видно, первым параметром в конструкторе анализатора я ожидаю объект типа Pawns, который я отсылаю из функции Pawns::move():
Analysis analysator(this, 1);
Что я хочу от объекта, который будет передан: как известно, при передаче в функцию аргумента по значению, он копируется. Я и ожидаю копию исходного объекта, чтобы с ним в анализаторе выполнить действия и дальше выкинуть эту копию (delete).
Но среда (пишу в Xcode на Mac OS X Lion) вот что мне говорит в том месте, где я описываю функцию-конструктор анализатора
Analysis::Analysis(Pawns field, int deep) {
this->field = field;
this->pawns = field.getPawns();
this->deep = deep;
};
Constructor for 'Analysis' must explicitly initialize the member 'field' which does'nt have the default constructor.
Я подозреваю, что запутался где-то в ссылках/указателях, перечитываю Страуструпа, но не помогает. Помогите, пожалуйста.
Что я хочу от объекта, который будет передан: как известно, при передаче в функцию аргумента по значению, он копируется.
Когда Вы передаете объект Pawns
в конструктор Analysis
, компилятору не обязательно делать копию - он видит, что объект не изменяется и его можно передать по ссылке. Это экономичней и быстрее. Но вообще то он вызывает конструктор копий (Pawns (const Pawns& p) {/*....*/}
).
Я и ожидаю копию исходного объекта, чтобы с ним в анализаторе выполнить действия и дальше выкинуть эту копию (delete).
компилятор сам удалит копию, если он ее создаст. Так как Вам не нужно удалять эту неявную копию, компилятор может проделать оптимизацию - не копировать даром объект. Если же Вы начинаете делать хитрые оптимизации, думаете обмануть компилятор...
Constructor for 'Analysis' must explicitly initialize the member 'field' which does'nt have the default constructor.
А здесь история другая. По умолчанию, если не один конструктор не создан, компилятор создаст их за Вас. Но как только Вы определили хотя бы один конструктор, компилятор не будет делать другие. Поэтому, так как Pawns
имеет конструктор Pawns(char side);
, то конструктора по умолчанию и конструктора копирования у него уже нет и компилятор не знает, как выполнить this->field = field;
.
Он говорит что надо использовать инициализатор или добавить конструктор по умолчанию. Потому что объект field создается до того как идет тело конструктора.
Analysis(Pawns field_, int deep) : field(field_ ) // необходимо наличие копирующего конструктора
Копирующий конструктор выглядит вот так
Pawns(const Pawns &field) - в нем должна быть константная ссылка.
Но так делать не стоит, потому что вы начнете копировать туда сюда, и возможно потом сделаете ход на копии, который естественно никаким образом не отобразиться на текущем состоянии игры.
Лучше так
class Analysis {
Pawns &field; // теперь ссылка
public:
Analysis(Pawns& field_, int deep) : field(field_ ) { // тут тоже ссылка
}
Код не тестировался и может не работать
Никак не могу найти исходный код g++ для linuxМне нужен именно исходный код
error C2784: '_RanIt1::difference_type std::operator -(std::move_iterator<_RanIt> &,const std::move_iterator<_RanIt2> &)' : could not deduce template argument for 'std::move_iterator<_RanIt> &' from 'std::_List_iterator<_Mylist>'
Добрый день, в общем нужно сделать простейший IMAP клиент на сокетах