У меня есть класс базы данных, и явный конструктор пытается подключиться к базе данных на основе пропущенных флагов, если он терпит неудачу, то он бросает. Это нежелательно (база данных не может быть создана другим приложением), поэтому я добавил пустой конструктор и конструкторы перемещения по умолчанию. В классе утилиты я жду, пока база данных не будет создана и не переместят новую.Default move constructor
В модульных тестах я вижу, что database_utils::connected()
возвращает false до того, как я вернусь и вернусь после перемещения. Однако, если я вызываю функцию, которая использует базу данных, я получаю ошибку library routine called out of sequence
. Это предполагает, что я не открыл базу данных или неверный оператор select, но конструкторы и деструктор вызываются в правильном порядке, и у меня есть модульные тесты для самой базы данных, где она создает базу данных, заполняет ее, и оператор select работает.
Так что мой вопрос: Является ли перемещение по умолчанию фактическим перемещением или нет? Если нет, что мне нужно сделать, чтобы получить ожидаемое поведение?
Пример кода:
class database
{
database() : connected_(false), database_(nullptr) { }
database(/* params */) : connected_(false), database_(nullptr) {
/* attempt connection, throw on fail */
connected_ = true;
}
database(database& other) = default;
database(database&& other) = default;
database& operator=(database&& other) = default;
~database() { /* clean up */ }
operator bool() const { return connected_; }
bool connected_;
sqlite3* database_;
};
class database_utils
{
database_utils() : db_() { }
void connect() {
db_ = std::move(database(/*params*/));
}
bool connected() { return db_; }
void example_select(/* params */) {
/* use db_ */
}
database db_;
};
Если вы хотите проверить, что ваш конструктор движений вызывается, вставьте в него инструкцию для отладки и посмотрите, выходит ли он. Разумеется, вы знаете, что в конструкторе по умолчанию нет ничего, что заставило бы его игнорировать указатели перемещенного объекта, такие как 'database_', что, безусловно, выглядит как ошибка. Вам нужно написать свой собственный конструктор движений, который делает правильные вещи. –
[OT]: конструктор копирования принимает аргумент arg по ссылке const. – Jarod42
Возможно, вы захотите, чтобы конструктор перемещения сбросил указатель перемещения, чтобы избежать двойной очистки. – Jarod42