 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Brian Wood Guest
|
Posted: Wed Oct 06, 2004 11:17 pm Post subject: polymorphism uses |
|
|
Hi,
I know it is common to write something like list<B*>, where B is a
base class. What I'm wondering is if people use non-base types in
a polymorphic way. Say list<Ia*>, where Ia is derived from B. The
reason I'm asking is I've been working on automating code that
send/receives a list<B*> or list<Ia*>. Before receiving either a "B*"
or "Ia*", a "Builder" function gets called to build an instance of
the correct type. These functions currently are generated as follows:
const unsigned int B_Num = 1202;
const unsigned int Ia_Num = 1203;
const unsigned int La_Num = 1204;
const unsigned int Lb_Num = 1205;
const unsigned int Ib_Num = 1206;
int
BBuilder(Buffer* buf, B*& p)
{
unsigned int typeNum;
ErrorWordsShepherd* ews;
if (!buf->PersistentRead(&typeNum, sizeof(typeNum))) {
ews = (ErrorWordsShepherd*) pthread_getspecific(errorKey);
ews->SetErrorWords(0, __FILE__, __LINE__);
return 0;
}
switch (typeNum) {
case B_Num:
p = new B;
break;
case Ia_Num:
p = new Ia;
break;
case La_Num:
p = new La;
break;
case Lb_Num:
p = new Lb;
break;
case Ib_Num:
p = new Ib;
break;
default:
ews = (ErrorWordsShepherd*) pthread_getspecific(errorKey);
ews->SetErrorWords(typeNum, __FILE__, __LINE__);
return 0;
}
return 1;
}
int
IaBuilder(Buffer* buf, Ia*& p)
{
unsigned int typeNum;
ErrorWordsShepherd* ews;
if (!buf->PersistentRead(&typeNum, sizeof(typeNum))) {
ews = (ErrorWordsShepherd*) pthread_getspecific(errorKey);
ews->SetErrorWords(0, __FILE__, __LINE__);
return 0;
}
switch (typeNum) {
case Ia_Num:
p = new Ia;
break;
case La_Num:
p = new La;
break;
case Lb_Num:
p = new Lb;
break;
default:
ews = (ErrorWordsShepherd*) pthread_getspecific(errorKey);
ews->SetErrorWords(typeNum, __FILE__, __LINE__);
return 0;
}
return 1;
}
The class hierarchy is:
B
Ia : B
Ib : B
La : Ia
Lb : Ia
I noticed that IaBuilder is a subset of BBuilder and have been
thinking about other options instead of the switch statements.
(I've read discussions about options to the dreaded switch on this
newsgroup...) But before working on that I wondered if non-base
classes get used much polymorphically. If they don't maybe I can
skip the rework. If you do use them that way please explain why.
Thanks,
Brian Wood
Ebenezer Enterprises
http://www.webebenezer.net
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
jakacki Guest
|
Posted: Tue Oct 12, 2004 10:43 am Post subject: Re: polymorphism uses |
|
|
| Quote: | I know it is common to write something like list<B*>,
where B is a base class. What I'm wondering is if people
use non-base types in a polymorphic way. Say list<Ia*>,
where Ia is derived from B.
|
I assume you are asking if people derive from concrete
classes. Yes, there are (few) legitimate cases to do so
(and actually many people overdo it).
| Quote: | The reason I'm asking is
I've been working on automating code that send/receives a
list<B*> or list<Ia*>. Before receiving either a "B*" or
"Ia*", a "Builder" function gets called to build an
instance of the correct type. These functions currently
are generated as follows:
|
[code edited]
| Quote: | int
BBuilder(Buffer* buf, B*& p)
{
....
switch (typeNum) {
case B_Num: ....
case Ia_Num: ....
case La_Num: ....
case Lb_Num: ....
case Ib_Num: ....
}
}
int
IaBuilder(Buffer* buf, Ia*& p)
{
....
switch (typeNum) {
case Ia_Num: ....
case La_Num: ....
case Lb_Num: ....
}
}
The class hierarchy is:
B
Ia : B
Ib : B
La : Ia
Lb : Ia
I noticed that IaBuilder is a subset of BBuilder and have
been thinking about other options instead of the switch
statements.
|
If the code is generated and not meant to be maintained by
hand, I would leave it as it is.
You may want to have a look at Andrei Alexandrescu's
"Modern C++ Design" chapter on factories, which discusses
solutions to your problem.
| Quote: | (I've read discussions about options to the
dreaded switch on this newsgroup...)
|
This does not apply here. Switch is dreaded only if it is
ubiquitious and hand-maintained. Your switches are neither.
| Quote: | But before working
on that I wondered if non-base classes get used much
polymorphically. If they don't maybe I can skip the
rework. If you do use them that way please explain why.
|
See e.g. my posting in the thread "Design question: class
with reference semantics".
BR
Grzegorz
--
Free C++ frontend library: http://opencxx.sourceforge.net
China from the inside: http://www.staryhutong.com
Myself: http://www.dziupla.net/gj/cv
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Brian Wood Guest
|
Posted: Mon Oct 18, 2004 7:07 pm Post subject: Re: polymorphism uses |
|
|
"jakacki" <jakacki_hates_spam (AT) acm (DOT) org> wrote
| Quote: | I know it is common to write something like list<B*>,
where B is a base class. What I'm wondering is if people
use non-base types in a polymorphic way. Say list<Ia*>,
where Ia is derived from B.
I assume you are asking if people derive from concrete
classes. Yes, there are (few) legitimate cases to do so
(and actually many people overdo it).
|
That is similar, but not exactly what I meant. To put it another
way, if someone derives from a concrete class which is derived from
an abstract base class, would they ever prefer an expression like,
list<Ia*> instead of list<B*>, where Ia is the concrete class and B
the base class.
| Quote: | The reason I'm asking is
I've been working on automating code that send/receives a
list<B*> or list<Ia*>. Before receiving either a "B*" or
"Ia*", a "Builder" function gets called to build an
instance of the correct type. These functions currently
are generated as follows:
[code edited]
int
BBuilder(Buffer* buf, B*& p)
{
....
switch (typeNum) {
case B_Num: ....
case Ia_Num: ....
case La_Num: ....
case Lb_Num: ....
case Ib_Num: ....
}
}
int
IaBuilder(Buffer* buf, Ia*& p)
{
....
switch (typeNum) {
case Ia_Num: ....
case La_Num: ....
case Lb_Num: ....
}
}
The class hierarchy is:
B
Ia : B
Ib : B
La : Ia
Lb : Ia
I noticed that IaBuilder is a subset of BBuilder and have
been thinking about other options instead of the switch
statements.
If the code is generated and not meant to be maintained by
hand, I would leave it as it is.
You may want to have a look at Andrei Alexandrescu's
"Modern C++ Design" chapter on factories, which discusses
solutions to your problem.
(I've read discussions about options to the
dreaded switch on this newsgroup...)
This does not apply here. Switch is dreaded only if it is
ubiquitious and hand-maintained. Your switches are neither.
|
That makes sense. The code isn't intended to be maintained
by hand, but I'm not as sure about the ubiquitous part. That
is what I'm getting at with asking about how polymorphism is
used. If it is common to have expressions like list<Ia*>, the
switches could become ubiquitous.
| Quote: | But before working
on that I wondered if non-base classes get used much
polymorphically. If they don't maybe I can skip the
rework. If you do use them that way please explain why.
See e.g. my posting in the thread "Design question: class
with reference semantics".
|
I read that but wasn't sure why you mentioned it.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
jakacki Guest
|
Posted: Tue Oct 19, 2004 4:43 pm Post subject: Re: polymorphism uses |
|
|
| Quote: | "jakacki" <jakacki_hates_spam (AT) acm (DOT) org> wrote in message
news:<8cc5209f1d3c2a9480a7986d75cebcd4 (AT) localhost (DOT) talkaboutprogramming.com>...
I know it is common to write something like list<B*>,
where B is a base class. What I'm wondering is if people
use non-base types in a polymorphic way. Say list<Ia*>,
where Ia is derived from B.
I assume you are asking if people derive from concrete
classes. Yes, there are (few) legitimate cases to do so
(and actually many people overdo it).
That is similar, but not exactly what I meant. To put it
another way, if someone derives from a concrete class
which is derived from an abstract base class, would they
ever prefer an expression like, list<Ia*> instead of
list<B*>, where Ia is the concrete class and B the base
class.
|
Yes. Consider
class Widget { .... };
class ClickableWidget : public Widget
{
....
virtual void Clicked(....) = 0;
};
class LabelWidget : public Widget
{ .... };
list<Widget*> elements;
list<ClickableWidget*> clickReceivers;
[...]
| Quote: | (I've read discussions about options to the dreaded
switch on this newsgroup...)
This does not apply here. Switch is dreaded only if it
is ubiquitious and hand-maintained. Your switches are
neither.
That makes sense. The code isn't intended to be
maintained by hand, but I'm not as sure about the
ubiquitous part.
|
if (ubiquitious && hand-maintained) { switch is dreaded; }
Your code is not intended to be hand-maintained, so where
is the problem?
| Quote: | That is what I'm getting at with asking about how
polymorphism is used. If it is common to have
expressions like list<Ia*>, the switches could become
ubiquitous.
|
Why does it bother you, if they are generated? The problem
is that hand-maintained and ubiquitious switches force you
to fix the code in many places every time the set of
swtiched-on values changes. In your case this tedious job
is delegated to the code generator, so why should you
worry?
| Quote: | But before working on that I wondered if non-base
classes get used much polymorphically. If they
don't maybe I can skip the rework. If you do use
them that way please explain why.
See e.g. my posting in the thread "Design question:
class with reference semantics".
I read that but wasn't sure why you mentioned it.
|
I thought you were asking about derivation from concrete
classes. Please ignore.
BR
Grzegorz
--
Free C++ frontend library: http://opencxx.sourceforge.net
China from the inside: http://www.staryhutong.com
Myself: http://www.dziupla.net/gj/cv
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Brian Wood Guest
|
Posted: Sun Oct 24, 2004 10:58 pm Post subject: Re: polymorphism uses |
|
|
"jakacki" <jakacki_hates_spam (AT) acm (DOT) org> wrote
| Quote: | "jakacki" <jakacki_hates_spam (AT) acm (DOT) org> wrote in message
news:<8cc5209f1d3c2a9480a7986d75cebcd4 (AT) localhost (DOT) talkaboutprogramming.com>...
I know it is common to write something like list<B*>,
where B is a base class. What I'm wondering is if people
use non-base types in a polymorphic way. Say list<Ia*>,
where Ia is derived from B.
I assume you are asking if people derive from concrete
classes. Yes, there are (few) legitimate cases to do so
(and actually many people overdo it).
That is similar, but not exactly what I meant. To put it
another way, if someone derives from a concrete class
which is derived from an abstract base class, would they
ever prefer an expression like, list<Ia*> instead of
list<B*>, where Ia is the concrete class and B the base
class.
Yes. Consider
class Widget { .... };
class ClickableWidget : public Widget
{
....
virtual void Clicked(....) = 0;
};
class LabelWidget : public Widget
{ .... };
list<Widget*> elements;
list<ClickableWidget*> clickReceivers;
[...]
|
OK. That helps.
| Quote: |
(I've read discussions about options to the dreaded
switch on this newsgroup...)
This does not apply here. Switch is dreaded only if it
is ubiquitious and hand-maintained. Your switches are
neither.
That makes sense. The code isn't intended to be
maintained by hand, but I'm not as sure about the
ubiquitous part.
if (ubiquitious && hand-maintained) { switch is dreaded; }
Your code is not intended to be hand-maintained, so where
is the problem?
That is what I'm getting at with asking about how
polymorphism is used. If it is common to have
expressions like list<Ia*>, the switches could become
ubiquitous.
Why does it bother you, if they are generated? The problem
is that hand-maintained and ubiquitious switches force you
to fix the code in many places every time the set of
swtiched-on values changes. In your case this tedious job
is delegated to the code generator, so why should you
worry?
|
I'm not worried, but from a quality of implementation stand-
point I think it matters. Poor quality may be more easily
overlooked in the case of computer generated code. As long
as it builds and runs correctly a lot of people may not know
it could be implemented better. I think the generated code
should be reasonable for a person to read in case they need to,
so avoiding mostly repetitive code is a step in the right
direction. The ClickableWidget example you mentioned makes me
lean toward reworking the implementation to use a factory
approach. Prior to that I was leaning toward leaving it alone.
| Quote: | But before working on that I wondered if non-base
classes get used much polymorphically. If they
don't maybe I can skip the rework. If you do use
them that way please explain why.
[...]
BR
Grzegorz
|
That is a formidable name you have.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|