469,330 Members | 1,257 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,330 developers. It's quick & easy.

How to solve this gracefully?

Hi, I have a problem involving some design issue.
I have two unrelated (that is, they do not derive from the same base)
classes:
ClassA
ClassB

Both have a quite similar interface, so they can be use interchangeably,
that is:

ptr = new ClassA;
ptr->f1();
ptr->f2();

To replace it with ClassB, all I need is changing the first line:

ptr = new ClassB;
ptr->f1();
ptr->f2();

(As I mentioned before, almost all the interface is identical)

This is OK when doing by hand. But I want to provide an option so a user can
toggle between both classes.
Problem is that as both classes are unrelated, I can't use a base pointer to
make instantiation..
So the most simple way I found is creating a proxy-like class, which
determines and forces the interface to be used:

class Iface {
public:
void f1();
void f2();
};

So doing:
class NewA : public ClassA, public Iface {
public:
void f1() { ClassA::f1(); }
void f2() { ClassA::f2(); }
};

and similarly
class NewB : public ClassB, public Iface {
public:
void f1() { ClassB::f1(); }
void f2() { ClassB::f2(); }
};

the I'm able to code:

Iface* ptr = new NewA;
or
Iface* ptr = new NewB;

and use them interchangeably.

Problem is -as you might have noticed- that the code to define the classes
is repetitive..

Is there a better way to solve this, and make it more elegant?

Note that in the future, I'll use ClassC with a not so similar interface. So
I find in this case the solution to be OK,
but in this specific case, maybe there's a shorter way?

Thanks.
Jul 23 '05 #1
3 1663
"Alex" <no@domain.com> schrieb im Newsbeitrag
news:da**********@nsnmpen3-gest.nuria.telefonica-data.net...
Hi, I have a problem involving some design issue.
I have two unrelated (that is, they do not derive from the same base)
classes:
ClassA
ClassB

Both have a quite similar interface, so they can be use interchangeably,
that is:

ptr = new ClassA;
ptr->f1();
ptr->f2();

To replace it with ClassB, all I need is changing the first line:

ptr = new ClassB;
ptr->f1();
ptr->f2();

(As I mentioned before, almost all the interface is identical)

This is OK when doing by hand. But I want to provide an option so a user
can toggle between both classes.
Problem is that as both classes are unrelated, I can't use a base pointer
to make instantiation..
So the most simple way I found is creating a proxy-like class, which
determines and forces the interface to be used:

class Iface {
public:
void f1();
void f2();
};
All member functions of the interface should be virtual (and probably pure).
You should also add a virtual d'tor.
So doing:
class NewA : public ClassA, public Iface {
public:
void f1() { ClassA::f1(); }
void f2() { ClassA::f2(); }
};

and similarly
class NewB : public ClassB, public Iface {
public:
void f1() { ClassB::f1(); }
void f2() { ClassB::f2(); }
};


You can use templates to save those repetitions:

template <class Z>
class NewZ: public Z, public Iface
{
public:
void f1() { Z::f1(); }
void f2() { Z::f2(); }
};

typedef NewZ<A> NewA;
typedef NewZ<B> NewB;

HTH
Heinz
Jul 23 '05 #2
>> This is OK when doing by hand. But I want to provide an option so a user
can toggle between both classes.
Problem is that as both classes are unrelated, I can't use a base pointer
to make instantiation..
So the most simple way I found is creating a proxy-like class, which
determines and forces the interface to be used:

class Iface {
public:
void f1();
void f2();
};


All member functions of the interface should be virtual (and probably
pure). You should also add a virtual d'tor.


Yeah, you're right!
So doing:
class NewA : public ClassA, public Iface {
public:
void f1() { ClassA::f1(); }
void f2() { ClassA::f2(); }
};

and similarly
class NewB : public ClassB, public Iface {
public:
void f1() { ClassB::f1(); }
void f2() { ClassB::f2(); }
};


You can use templates to save those repetitions:

template <class Z>
class NewZ: public Z, public Iface
{
public:
void f1() { Z::f1(); }
void f2() { Z::f2(); }
};

typedef NewZ<A> NewA;
typedef NewZ<B> NewB;


This is great, thanks. So the method I use seems to be the best way to solve
this?
Can this be considered like a proxy pattern approach?
Jul 23 '05 #3
"Alex" <no@domain.com> schrieb im Newsbeitrag
news:da**********@nsnmpen3-gest.nuria.telefonica-data.net...
This is great, thanks. So the method I use seems to be the best way to
solve this?


I would never call a method to do something "the best one". There is always
the possibility, that someone comes up with a better solution. There are
only good solutions and bad solutions, and as far as I understood the
problem you wanted to solve, I wouldn't call your solution a bad one. Your
first approach had the problem that you had to manually create many wrappers
for all your types, but that has been simlyfied using a template and letting
the compiler to do the dirty work.

HTH
Heinz
Jul 23 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by William F. Robertson, Jr. | last post: by
6 posts views Thread by - Steve - | last post: by
7 posts views Thread by Frank | last post: by
6 posts views Thread by Tim Chase | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.