473,326 Members | 2,175 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

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 1827
"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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: KB | last post by:
Hi, I want to write a Python script that controls and automates a Windows GUI computation program. My problem is that I do not know how to quit the Windows GUI program gracefully with a...
2
by: Gary | last post by:
Hi, there, I have an application running on remote machine, and would like to close it gracefully. Like a human go to there, push the stop button, and close it after several seconds. How to...
4
by: William F. Robertson, Jr. | last post by:
One of my developers came to me with this question and I don't have an answer for them. The only suggestion I had for them was to change the return to a output parameter and put a try catch around...
6
by: - Steve - | last post by:
I'm using Forms Based Authentication. I've written my code so that when a user does something but has timed out, it gracefully logs them out and asks them to log back on. I do this with . . ...
6
by: Mark | last post by:
Hello, I'm trying to handle HttpRequestValidationException. If a hacker enters certain values into a textbox, like "<script>", it will trigger this error. I understand why .Net has this, but I...
7
by: Frank | last post by:
Hi, I have a console app that I want to stop gracefully by another program. The console app already has code to intercept control-c and logoff and so on. But how do I send a control-c to that...
6
by: Tim Chase | last post by:
While working on a Jumble-esque program, I was trying to get a string into a character array. Unfortunately, it seems to choke on the following import random s = "abcefg" random.shuffle(s) ...
1
by: Ryan Liu | last post by:
Hi, I have a 100 clients/ one server application, use ugly one thread pre client approach. And both side user sync I/O. I frequently see the error on server side(client side code is same, but...
4
!NoItAll
by: !NoItAll | last post by:
I have a program that needs to access the files that are open by another program on the computer. When my application comes up I can easily see if the other application is running with the .net...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.