默认移动构造函数
Default move constructor
我有一个数据库class,显式构造函数尝试根据传入的标志连接到数据库,如果失败则抛出。这是不需要的(数据库可能不是由另一个应用程序创建的)所以我添加了一个空白构造函数和默认移动构造函数。在实用程序 class 中,我等到数据库创建完毕并移入一个新数据库。
在单元测试中,我看到 database_utils::connected()
returns 在我移动之前为 false,在移动之后为 true。但是,如果我调用一个使用数据库的函数,我会收到 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_
是指针。指针移动实际上是复制。
然后在析构函数中,database_
会被删除。
因为"old"和"new"对象的database_
指向相同的内存位置,"new"对象将处于不稳定状态,因为database_
将指向超空间。
如果你能把database_
改成智能指针,默认的移动构造函数就可以正常工作了。
或者,制作您自己的移动构造函数来移动所有内容,并将 database_
设置为 nullptr
并将 connected_
设置为 false
。
我有一个数据库class,显式构造函数尝试根据传入的标志连接到数据库,如果失败则抛出。这是不需要的(数据库可能不是由另一个应用程序创建的)所以我添加了一个空白构造函数和默认移动构造函数。在实用程序 class 中,我等到数据库创建完毕并移入一个新数据库。
在单元测试中,我看到 database_utils::connected()
returns 在我移动之前为 false,在移动之后为 true。但是,如果我调用一个使用数据库的函数,我会收到 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_
是指针。指针移动实际上是复制。
然后在析构函数中,database_
会被删除。
因为"old"和"new"对象的database_
指向相同的内存位置,"new"对象将处于不稳定状态,因为database_
将指向超空间。
如果你能把database_
改成智能指针,默认的移动构造函数就可以正常工作了。
或者,制作您自己的移动构造函数来移动所有内容,并将 database_
设置为 nullptr
并将 connected_
设置为 false
。