Here is my scenario:
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;
}
When Database object is destroyed, I want that the sqlite3 object is closed. In this form, it seems that it can be an unsafe approach since if I copy the object and I destroy it, then the copied object is in an invalid state.
In your opinion, what is the best way to proceed? I was thinking about singleton class but I'm not sure about this.
Make your class noncopyable. In C++11:
class Database {
public:
Database(const Database&) = delete;
Database& operator=(const Database&) = delete;
};
In C++03:
class Database {
private: // inaccessible
Database(const Database&);
Database& operator=(const Database&);
};
Or with Boost:
#include <boost/noncopyable.hpp>
class Database : private boost::noncopyable {
};
In C++11 I would also make the object Movable
by giving it a MoveConstructor and Move assignment operators. There you would assign the handle (or whatever your db gives you) to the new object and use some flag in the old object to indicate that nothing needs to be closed.
Don't forget to implement swap
as well!
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 */ }
};
Also: setting some value to false in your destructor has no effect. Nothing should ever be able to see the change.
Or using a unique_ptr
/shared_ptr
with a custom deleter:
struct CloseDatabase {
void operator()(sqlite* x) { sqlite3_close(x); }
};
typedef std::unique_ptr<sqlite3, CloseDatabase> Database;