+1  A: 

As I understand from this problem (breaking encapsulation during reading and writing to DB or SNMP connection), first you need a proper design to eliminate these "friend"s. please define an abstract class for connections (i.e. IDBConnection) also persistent objects (i.e. IPersistent). You may use "Abstract Factory" pattern to create them. Furthermore, isolate load and save methods to another class and use "visitor pattern" to initialize or save your objects from/to your DB.

Another point, if you need an embedded DB for your application, use SQLite there are tons of good C++ wrappers for it. Hope it helps

baris_a
A: 

Here's how I might do it in pseudo-code:

class Result { 
public: 
    int     getField(name); 
    string  getField(name); 
}

class Connection { 
public: 
    void save(list<pair<string, string>> properties); 
    Result query(); 
} 

class DBConnection { 
private: 
    class DBResult : public Result {  
    } 
public: 
    Result query() { 
        return ( DBResult ); 
    } 
    void save
}

class Object { 
public: 
    void load(Result); 
    void save(Connection) { 
        // make properties list 
        connection.save(properties); 
    } 
} 

Without Java-style reflection, that's probably how I'd do it without getting into "friend"-ship relationships. Then you're not tightly coupling the knowledge of connection logic into the connection classes.

...

You could also build template functions to do it, but you'd still need a friend relationship.

class Object { 
public: 
    friend template<class Conn, class Obj> load(Conn c, Obj o);
    friend template<class Conn, class Obj> save(Conn c, Obj o);
} 

load<Connection, Object>(Connection c, Object o) { 
    //access o.private to load into c 
} 

I'm not sure which way I'd go. In one respect, you encapsulate load/save logic in your Object classes, which is great for locality, but it might tightly couple your persistence and business logic all in one location.

Chris Kaminski