【问题标题】:What's the proper way to handle an RAII member variable?处理 RAII 成员变量的正确方法是什么?
【发布时间】:2014-05-11 12:50:49
【问题描述】:

我是 C++ 新手,还没有完全理解 RAII 模式。我正在编写一个通过SQLiteC++ 使用sqlite 数据库的类。以下是一些使用有效数据库的示例代码:

void test() {
    SQLite::Database db(TestDbPath(), SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);

    db.exec("DROP TABLE IF EXISTS test");
    db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, foobar TEXT)");
}

我想做的是使用班级中的SQLite::Database。这样的事情会起作用:

class DBUser
{
private:
    SQLite::Database *db;

public:
    explicit DBUser(std::string &path) {
        db = new SQLite::Database(path, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
    }
    ~DBUser() {
        delete db;
    }

    void test() {
        db->exec("DROP TABLE IF EXISTS test");
        db->exec("CREATE TABLE test (id INTEGER PRIMARY KEY, foobar TEXT)");
    }
}

这是最好的方法吗?有没有更惯用/优雅的方式来完成这个没有指针?

【问题讨论】:

  • 一个简单的数据成员?
  • 如果有,请使用std::shared_ptr,如果没有,请使用 Boost 库中的 boost::shared_ptr
  • 在这种情况下使用std::unique_ptr 可能是合适的。考虑到语义,我认为您不能只共享这些指针。

标签: c++ class pointers constructor raii


【解决方案1】:

只要有一个对象作为成员:

class DBUser
{
private:
    SQLite::Database db;

public:
    explicit DBUser(std::string &path) :
        db (path, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE) 
    {

    }
    void test() {
        db.exec("DROP TABLE IF EXISTS test");
        db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, foobar TEXT)");
    }
}

【讨论】:

  • 线索就在标题中:RAII 几乎总是意味着使用对象而不是指针。
  • 啊,我明白了,我只是不确定如何初始化它...这是否等同于){ db = SQLite::Database db(path, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); }?如果是这样,复制语义到底是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多