Reputation: 22500
I created the following class for an sqlite3 connection:
class SqliteConnection
{
public:
sqlite3* native;
SqliteConnection (std::string path){
sqlite3_open_v2 (path.c_str(), &native, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
}
~SqliteConnection (){
sqlite3_close(native);
}
}
and then one can initialize a connection as follows
SqliteConnection conn("./database.db");
However, I would like to be able to share this connection, store it as a member in classes, etc., and the trouble is with the default assignment operator operator=
. Doing something like
SqliteConnection conn("./database.db");
SqliteConnection conn1 = conn;
would lead to two sqlite3_close calls on the database pointer as each variable goes out of scope. How do you overcome this difficulty with RAII when you need to assign your resource to a different variable?
Upvotes: 3
Views: 714
Reputation: 248199
You have four basic options:
shared_ptr
. This is the least efficient, but it's the most general solution.auto_ptr
does. a = b
results in a
taking ownership of b
's connection, and b
being set to a null value, as an empty, unusable object.Upvotes: 0
Reputation: 99074
For shared resources you will have to keep track of wether references to them exist, e.g. using reference counting. One implementation is boost::shared_ptr
with a custom deleter:
class SqliteConnection {
boost::shared_ptr<sqlite3> native;
public:
SqliteConnection(const std::string& path)
: native(init_connection(path), &destroy_connection)
{}
// ...
};
sqlite3* init_connection(const std::string& path) {
// ...
return ptr;
}
void destroy_connection(sqlite3* p) {
sqlite3_close(p);
}
Upvotes: 9
Reputation: 96889
Put the connection in a shared_ptr. On assignment all what you have to do is to assign "shared_ptr"s to have shared ownership of the resource(connection). Otherwise you have to implement shared ownership for your class which already has been done in boost and is included in C++0x.
Upvotes: 3