Re: Policy Based Design Question
DerrickH wrote:
On May 23, 11:29 am, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
DerrickH wrote:
I have a template class with three policies: PolicyA, PolicyB, and
PolicyC. The design dilemma I am having is that B and C depend upon A,
but I would like my Host class to derive from all three. In all three
cases I would like to take advantage of enriched policies.
template <
class PolicyA,
template <class> class PolicyB,
template <class> class PolicyC
class Host: public PolicyA, public PolicyB<PolicyA>, public
PolicyC<PolicyA>
{
};
How do I structure the policy classes A, B, and C such that B and C
have access to A (Host)?
The question is a bit vague. Do you need the instances of the base
classes B and C (base class subobjects of 'Host') to have access to the
instance of the base class A (the subobject of the same 'Host')? In
that case you need to construct PolicyB and PolicyC with, say, a pointer
to 'PolicyA' object. So, when you construct the Host, you'd do
something like this
Host()
: PolicyA()
, PolicyB<PolicyA>(this)
, PolicyC<PolicyA>(this)
{
}
Provided that 'PolicyB' and 'PolicyC' can be constructed from a pointer
to 'PolicyA', 'this' expression will be converted to 'PolicyA*', and the
other two subobjects will receive the correct address of 'PolicyA'.
If that's not what you're asking, then please show us what kind of
"access" you expect (better in a C++ form) so it would be possible to
understand what you're trying to accomplish.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Thank you, Victor. Sorry for being vague. That is exactly what I'm
looking for. And, actually after giving it some thought, C also
depends upon B. Let me make it a little more clear if I can. Basically
I'm trying to model a service provider which provides two different
services.
template <
class ConnectionDetails,
template <class> class Service1,
template <class, class> class Service2
class service_provider :
public ConnectionDetails,
public Service1<ConnectionDetails>,
public Service2<ConnectionDetails,
Service1<ConnectionDetails> >
{
public:
service_provider() :
ConnectionDetails(),
Service1<ConnectionDetails>(this),
Service2<ConnectionDetails,
Service1<ConnectionDetails> >(this, this)
{
}
};
The solution you provided is what I'm looking for, but is there a way
to avoid the this->copy_of_this-> extra level of indirection that
would result? Or, even better, is there a better way to model this
type of relationship?
I am honestly not sure what kind of "extra level of indirection" you are
talking about. Here is a trial implementation, enjoy.
#include <ostream>
template <class D> struct CD
{
D d;
CD(D d) : d(d) {}
std::ostream& dump(std::ostream& os) const { return os << d; }
};
template <class CD> class S1
{
CD* cd;
public:
S1(CD* cd_) : cd(cd_) {}
std::ostream& dump(std::ostream& os) const {
os << "S1(";
cd->dump(os);
return os << ")";
}
};
template <class CD, class S1> class S2
{
CD* cd;
S1* s1;
public:
S2(CD* cd_, S1* s1_) : cd(cd_), s1(s1_) {}
std::ostream& dump(std::ostream& os) const {
os << "S2("; cd->dump(os);
os << ",";
s1->dump(os);
return os << ")";
}
};
template < class ConnectionDetails,
template <class> class Service1,
template <class, class> class Service2 >
class service_provider :
public ConnectionDetails,
public Service1<ConnectionDetails>,
public Service2<ConnectionDetails, Service1<ConnectionDetails> >
{
typedef ConnectionDetails A;
typedef Service1<ConnectionDetails> B;
typedef Service2<ConnectionDetails, Service1<ConnectionDetails> > C;
public:
service_provider(ConnectionDetails const& a) :
ConnectionDetails(a),
Service1<ConnectionDetails>(this),
Service2<ConnectionDetails, Service1<ConnectionDetails> >(this, this)
{
}
std::ostream& dump(std::ostream& os) const {
os << "provider (";
static_cast<A const*>(this)->dump(os); os << ",";
static_cast<B const*>(this)->dump(os); os << ",";
static_cast<C const*>(this)->dump(os); os << ")";
return os;
}
};
#include <iostream>
int main()
{
CD<int> cd(42);
service_provider<CD<int>,S1,S2> sp(cd);
sp.dump(std::cout);
std::cout << std::endl;
}
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask