|
Boost : |
From: Larry Evans (jcampbell3_at_[hidden])
Date: 2002-01-17 20:15:25
How would smart_ptr handle pointee multiple inheritance? For
example, how could it do what prox_mi does in the attached
file? The subj_base class could be replaced with something like
a reference count base class, either intrusive or not.
//Purpose:
// prototype prox for multi-inherited subjects
//Result:
#include <cstddef>
#include <iostream>
using namespace std;
//----------------------
struct
subj_base
{
}
;//end subj_base
//----------------------
struct
prox_base
{
typedef
subj_base
subj_type
;
typedef
prox_base
my_type
;
prox_base(my_type const&a_prox)
: m_subj(a_prox.m_subj)
{}
my_type const&
operator=(my_type const&a_prox)
{ m_subj = a_prox.m_subj
; return *this
;}
my_type const&
operator=(subj_type*a_subj)
{ m_subj = a_subj
; return *this
;}
subj_type*
get_subj(void)const
{ return m_subj
;}
protected:
prox_base(subj_type*a_subj)
: m_subj(a_subj)
{}
void
put_subj(subj_type*a_subj)
{ m_subj = a_subj
;}
private:
subj_type*
m_subj
;
}
;//end prox_base struct
//----------------------
template
< typename Subject
>
struct
prox_make
: public prox_base
{
prox_make(void)
: prox_base(new Subject)
{}
Subject*
get_subj(void)const
{ return static_cast<Subject*>(prox_base::get_subj())
;}
}
;//end prox_make
//----------------------
template
< typename SubjTo
, typename SubjFrom=SubjTo
>
struct
prox_mi
: public prox_base
{
typedef
prox_base::subj_type
subj_base
;
typedef
prox_mi<SubjTo,SubjFrom>
my_type
;
template
< typename SubjDerived
>
subj_base*
from2base(SubjDerived*a_subj)
{
; SubjTo*to_subj=a_subj //check conversion
; subj_base*base_subj=static_cast<SubjDerived*>(to_subj)
; return base_subj
;}
prox_mi(prox_make<SubjFrom>const&a_make)
: prox_base(from2base(a_make.get_subj()))
{}
template
< typename SubjDerived
>
prox_mi(prox_mi<SubjDerived,SubjFrom>const&a_prox)
: prox_base(from2base(a_prox.get_to()))
{}
template
< typename SubjDerived
>
my_type const&
operator=(prox_mi<SubjDerived,SubjFrom>const&a_prox)
{
; prox_base::put_subj(from2base(a_prox.get_to()))
; return *this
;}
subj_base*
get_base(void)const
{
; subj_base*base_subj=static_cast<subj_base*>(get_subj())
; return base_subj
;}
SubjTo*
get_to(void)const
{
; SubjFrom*f_subj=static_cast<SubjFrom*>(get_base())
; SubjTo*t_subj = f_subj
; return t_subj
;}
}
;//end prox_mi
//----------------------
struct subjA
: public subj_base
{ int m_a;
subjA(void)
: m_a(0)
{}
}
;
//----------------------
struct subjB
{ char m_b;
}
;
//----------------------
struct subjC
{ bool m_c;
}
;
//----------------------
struct subjAB
: public subjA
, public subjB
{
}
;
//----------------------
struct subjABC
: public subjAB
, public subjC
{
}
;
//----------------------
template
< typename subjTO
, typename subjMI
>
void
test(const char*test)
{
; prox_make<subjMI> sMI
; typedef prox_base::subj_type subj_base
; prox_mi<subjTO,subjMI> pMI(sMI)
; subj_base*pBase=pMI.get_base()
; subjTO*pTO=pMI.get_to()
; char*cBase=static_cast<char*>((void*)pBase)
; char*cTO=static_cast<char*>((void*)pTO)
; ptrdiff_t d=cTO-cBase
; cout<<test<<":ptrdiff="<<d<<endl
;}
//----------------------
int
main(void)
{
; int result=0
; typedef subjAB subjMI
; test<subjAB,subjMI>("cAB-cBase")
; test<subjA,subjMI>("cA-cBase")
; test<subjB,subjMI>("cB-cBase")
; {
; typedef subjABC subjMI
; typedef subjAB subjDER
; typedef subjB subjTO
; prox_make<subjMI> a_make
; prox_mi<subjDER,subjMI> a_der(a_make)
; subjDER*der_subj= a_der.get_to()
; subjTO*to_subj= der_subj
; prox_mi<subjTO,subjMI> a_to(a_der)
; to_subj=a_to.get_to()
; ptrdiff_t d = static_cast<char*>((void*)to_subj)-static_cast<char*>((void*)der_subj)
; cout<<"ptrdiff to_subj-der_subj = "<<d<<endl
;}
; return result
;}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk