Search code examples
c++raiiassignment-operator

RAII and assignment


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?


Solution

  • 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);
    }