c++ - RAII - store `void*&` or `void**` -
i working on design wrapper class provide raii function. original use case follows:
void* tid(null); openfunc(&tid); closefunc(&tid);
after introduce new wrapper class, expect future usage follows:
void* tid(null); ttta(tid);
or
tttb(tid);
question:
which implementation ttta
or tttb
better? or bad , please introduce better one.
one thing have concern after resource allocated, id
accessed outside of class ttta
or tttb
until id
destroyed. based on understanding, design should not have side-effect that.
thank you
class ttta : boost::noncopyable { public: explicit ttta(void *id) : m_id(id) { openfunc(&m_id); // third-party allocate resource api } ~ttta() { closefunc(&m_id); // third-party release resource api } private: void* &m_id; // have store value in order release in destructor } class tttb : boost::noncopyable { public: explicit tttb(void *id) : m_id(&id) { openfunc(m_id); // third-party allocate resource api } ~tttb() { closefunc(m_id); // third-party release resource api } private: void** m_id; // have store value in order release in destructor }
// pass-in pointers comparison
class tttd { public: tttd(int* id) // take reference, not copy stack. : m_id(&id) { *m_id = new int(40); } private: int** m_id; }; class tttc { public: tttc(int* &id) : m_id(id) { m_id = new int(30); } private: int* &m_id; }; class tttb { public: tttb(int* id) : m_id(id) { m_id = new int(20); } private: int* &m_id; }; class ttta { public: ttta(int** id) : m_id(id) { *m_id = new int(10); } private: int** m_id; }; int main() { ////////////////////////////////////////////////////////////////////////// int *pa(null); ttta a(&pa); cout << *pa << endl; // 10 ////////////////////////////////////////////////////////////////////////// int *pb(null); tttb b(pb); //cout << *pb << endl; // wrong ////////////////////////////////////////////////////////////////////////// int *pc(null); tttc c(pc); cout << *pc << endl; // 30 ////////////////////////////////////////////////////////////////////////// int *pd(null); tttd d(pd); cout << *pd << endl; // wrong }
both break in bad ways.
ttta stores reference variable (the parameter id) that's stored on stack.
tttb stores pointer variable that's stored on stack.
both times, variable goes out of scope when constructor returns.
edit: since want values modifiable, simplest fix take pointer reference; make tttc reference actual pointer instead of local copy made when taking pointer non reference parameter;
class tttc : boost::noncopyable { public: explicit ttta(void *&id) // take reference, not copy stack. : m_id(id) ... private: void* &m_id; // have store value in order release in destructor }
the simple test breaks versions add print
method classes print pointer value , do;
int main() { void* = (void*)0x200; void* b = (void*)0x300; { ttta ta(a); ttta tb(b); ta.print(); tb.print(); } }
both ttta , tttb print both values 0x300 on machine. of course, result ub; result may vary.
Comments
Post a Comment