inheritance headache....

G

Grizlyk

Grizlyk said:
//adapter
template<class Tadapted, class Towner=Tadapted>
class Adapted_Description: public abstractDescription

Well, i forget to say, that often CTT will be not derived from
abstractDescription.

In fact, only follwing code was not-virtual
//new interface
public:
Target* create()
{ return new Target; }

So, there is example of total not-virtual class-adapter

//adapter
template<class Tadapted, class Towner=Tadapted>
class Adapted_Description
{

...

//old interface
public:

for each
adapted::method
//not-virtual call
{ adapted.adapted::method; }

};

Maksim A. Polyanin
http://grizlyk1.narod.ru/cpp_new
 
B

bob

* James Kanze:




    [...]
How do you know?  There was nothing in the original posting to
suggest it, and it's rather the exception, and not the rule.
On the contrary, from the original posting:
* (e-mail address removed):
Now somewhere, actually EVERYWHERE in this legacy  code I see
statements like this;
// semi pseudo with
abstractTarget* createTarget(abstractDescription* desc)
{
// shortcut pseudo code for dynamic cast< > ()
   if ( desc is concreteDesc1)
   {
     return new concreteTarget1();
   }
   else if (desc is concreteDesc2)
   {
     return new concreteTarget2();
   }
   else
   {
     return 0;
   }
}
Notice that no information about the created objects is retained.
Hence, as I figure it, the caller has the responsibility for destroying
them.
In other words, since no information is given, you suppose the
exceptional case, rather than the usual.

No.  First, there's lots of information in the example above.  Second,
what's "usual" for you is, I suspect, rather different than the norm in
industry, especially for old legacy code; a better term might be
"ideal", that you're wondering why I'm assuming the code isn't ideal...

Can you really imagine the programmer who created the above, doing
registration for events in e.g. concreteTarget1's constructor?

I can't  --  but then, if the OP states otherwise (which would be
inconsistent with comments else-thread), I'd have to revise my opinion.

Cheers, & hth.,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?- Hide quoted text -

- Show quoted text -

you're correct Alf.
 
A

AnonMail2005

Hi experts,

I have a construction problem that I need to fix;

currrently the following hierarchy exists;

       abstractTarget
       /           \
      /             \
 conreteTarget1  concreteTarget2

       abstractDescription (this class family can NOT be modified)
         /          \
   concreteDesc1  concDesc1

Now somewhere, actually EVERYWHERE in this legacy  code I see
statements like this;

// semi pseudo with
abstractTarget* createTarget(abstractDescription* desc)
{

// shortcut pseudo code for dynamic cast< > ()
   if ( desc is concreteDesc1)
   {
     return new concreteTarget1();
   }
   else if (desc is concreteDesc2)
   {
     return new concreteTarget2();
   }
   else
   {
     return 0;

   }

}

Now I CANT add methods to abstractDescription, if I could I would have
a method;

class abstractDescription
{
  AbstractTarget* create(AbstractDescription* desc)
  {
      desc->create();
  }

}

and each ConcreteDescription subclass would override as needed the
create the right concreteTarget.

BUT I cant do that as the AbstractDesciption family of objects cannot
be modified in any way. Can anybody help me out?

Im trying to tease out a solution here but I always get stung with a
cast or such like. anybody out there have any ideas?

cheers

G

As others have pointed out, you should use a factory.

First cut, put the if statement inside a factory and
keep that logic in exactly one place instead of all
over your code.

Second cut, you can have your concrete classes register
their creation methods with the factory so you can
eliminate the if statement. Modern C++ Design has a
good example of how to do this.

One of the problems in your above code is that you are
passing an already constructed desc class into the
contructor of the target class. But it looks like there
is a one-to-one correspondence between target classes and
desc class. That means you can have the target class
constructor just create it's appropriate desc class
If that's not possible, then I'd go with the typeid as
someone else has suggested.
 
J

James Kanze

* James Kanze:
* James Kanze:
[...]
How do you know? There was nothing in the original posting to
suggest it, and it's rather the exception, and not the rule.
On the contrary, from the original posting:
* (e-mail address removed):
Now somewhere, actually EVERYWHERE in this legacy code I see
statements like this;
// semi pseudo with
abstractTarget* createTarget(abstractDescription* desc)
{
// shortcut pseudo code for dynamic cast< > ()
if ( desc is concreteDesc1)
{
return new concreteTarget1();
}
else if (desc is concreteDesc2)
{
return new concreteTarget2();
}
else
{
return 0;
}
}
Notice that no information about the created objects is retained.
Hence, as I figure it, the caller has the responsibility
for destroying them.
In other words, since no information is given, you suppose
the exceptional case, rather than the usual.
No. First, there's lots of information in the example above.
Second, what's "usual" for you is, I suspect, rather different
than the norm in industry, especially for old legacy code; a
better term might be "ideal", that you're wondering why I'm
assuming the code isn't ideal...

Or maybe the reverse. It was the usual pattern, in industry, 15
years ago, but it's true that I've not seen it presented in many
recent C++ texts.
Can you really imagine the programmer who created the above,
doing registration for events in e.g. concreteTarget1's
constructor?

Well, you may have a point there:). Using a map of factory
objects was also a usual pattern in industry 15 years ago---if
the OP is unfamiliar with it, then maybe he's unfamiliar with
the other patterns as well.

Anyway, I think we agree in principle: if the constructor
registers the object (where ever), then a raw pointer is in
order. If it doesn't, then using an auto_ptr to hold the object
until it is registered is the more or less standard convention.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,280
Latest member
BGBBrock56

Latest Threads

Top