Re: C++ Design question
Lance Diduck wrote:
This is the idea:
//better ways to do this but this is the essentials
//same as COM Interface IID
// better and faster than strings
enum{base1ID ,base2ID ,base2ID };
template< class T>struct interface2id;
struct iBase2{
virtual tr1::shared_ptr<iBase2> GetInterface(int ,iBase2**) const=0;
//other stuff for internals
//add_ref, release, add_ref_copy, weak_ref, weak_release, etc
};
struct base1: iBase2{};
struct base2: iBase2{};
struct base3: iBase2{};
//a few helpers
template< class base1> struct interface2id{static const int id=base1ID
};
template< class base2> struct interface2id{static const int id=base2ID
};
template< class base3> struct interface2id{static const int id=base3ID
};
class myClass: public base1, public base2, public base3
,mystuff::enable_shared_from_this<myClass>//has counter mechanism
inside
{
tr1::shared_ptr<iBase2>
GetInterface( int arg,iBase2**_p)const{
//*_p ==0 precondition
switch (arg){
case interface2id<base1>::id;
case interface2id<base2>::id;
case interface2id<base3>::id;
*_p = this;
break;
}
return shared_from_this();
}
};
template <class To>mystuff::shared_ptr<To>
interface_cast3( mystuff::shared_ptr<iBase2> const& _r ){
iBase2*_a=0;
//hold a pointer to the object while we construct
// a new pointer (needed for MT)
mystuff::shared_ptr<iBase2> b=
_r->GetInterface(interface2id<To>::id,&_a);
//THIS ONLY WORKS WITH INTRUSIVE REFERENCE COUNTING
//NOT STANDARD
if (_a) return mystuff::shared_ptr< To>(static_cast<To>(_a));
return mystuff::shared_ptr<To>();//empty
}
This would probably work with boost::instrusive_ptr, if you dont need
weak_ptrs support (probably not)
There are even more methods, however, this should be enough to chew on
for a while.
Hope this helps
Correction: Above should read something like
struct iBase2{
virtual tr1::shared_ptr<iBase2> GetInterface(int ,void**) const=0;
};
class myClass: public base1, public base2, public base3
,mystuff::enable_shared_from_this<myClass>//has counter mechanism
inside
{
tr1::shared_ptr<iBase2>
GetInterface( int arg,void**_p)const{
//*_p ==0 precondition
switch (arg){
case interface2id<base1>::id;
*_p = static_cast<base1>(this);
break;
case interface2id<base2>::id;
*_p = static_cast<base2>(this);
break;
case interface2id<base3>::id;
*_p = static_cast<base3>(this);
break;
}
return shared_from_this();
}
};
template <class To>mystuff::shared_ptr<To>
interface_cast3( mystuff::shared_ptr<iBase2> const& _r ){
iBase2*_a=0;
mystuff::shared_ptr<iBase2> b=
_r->GetInterface(interface2id<To>::id,&_a);
if (_a) return mystuff::shared_ptr< To>(reinterpret_cast<To>(_a));
return mystuff::shared_ptr<To>();//empty
}
Reason: without virtual inheritance of iBase, just which iBase you are
referrring to is ambiguous.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]