encupsalator对象的C++规则为3

the*_*man 0 c++ encapsulation object

这是我的场景:

class Database {

    public:
        Database();
        ~Database();

        void close();
                ...

    private:

        sqlite3 *database; //SQLITE3 OBJECT
        bool isOpenDb;
        ...

};

Database::Database() {

    database = 0;
    filename = "";
    isOpenDb = false;
}

Database::~Database() {
    close();
}

void Database::close() {
    sqlite3_close(database); 
    isOpenDb = false;
}
Run Code Online (Sandbox Code Playgroud)

Database对象被销毁时,我想要关闭sqlite3对象.在这种形式中,似乎它可能是一种不安全的方法,因为如果我复制对象并将其销毁,则复制的对象处于无效状态.

在您看来,最好的方法是什么?我在想单身课,但我不确定.

pmr*_*pmr 5

让你的课程不可复制.在C++ 11中:

class Database {
public:
  Database(const Database&) = delete;
  Database& operator=(const Database&) = delete;
};
Run Code Online (Sandbox Code Playgroud)

在C++ 03中:

class Database {
private: // inaccessible 
  Database(const Database&);
  Database& operator=(const Database&);
};
Run Code Online (Sandbox Code Playgroud)

或者使用Boost:

#include <boost/noncopyable.hpp>
class Database : private boost::noncopyable {
};
Run Code Online (Sandbox Code Playgroud)

在C++ 11中,我还Movable通过给它一个MoveConstructor和Move赋值运算符来创建对象.在那里,您可以将句柄(或您的数据库提供的任何内容)分配给新对象,并在旧对象中使用一些标志来指示不需要关闭任何内容.

别忘了实施swap!

class Database {
  // This might look odd, but is the standard way to do it without a namespace.
  // If you have a namespace surrounding Database, put it there.
  friend void swap(Database& a, Database& b) { /* code to swap a and b */ }
};
Run Code Online (Sandbox Code Playgroud)

另外:在析构函数中将某些值设置为false无效.什么都不应该看到变化.

或者使用unique_ptr/ shared_ptr与自定义删除器:

struct CloseDatabase {
  void operator()(sqlite* x) { sqlite3_close(x); }
};

typedef std::unique_ptr<sqlite3, CloseDatabase> Database;
Run Code Online (Sandbox Code Playgroud)