Preserve dynamic type information

D

doomer

Hello,

I'm trying to build a set of classes that act as the handlers for a
simple expression parser, and i'm wondering how to preserve the
dynamic type information from derived classes. An example will help
illustrate what I have in mind...

class Numeric
{
// contains discriminated union to hold data and identify data
type

virtual TypeDescritor Type() const;

virtual bool IsPromotableTo(const Numeric &numeric);

virtual Numeric Promote(const Numeric &rhs) const;

virtual Numeric Add(const Numeric &rhs) const;

friend Numeric operator+(const Numeric &lhs, const Numeric &rhs);
}

Numeric operator+(const Numeric &lhs, const Numeric &rhs)
{
if(lhs.IsPromotableTo(rhs)){
return rhs.Add(lhs.Promote(rhs));
}
else if(rhs.IsPromotableTo(lsh)){
return lhs.Add(rhs.Promote(rhs));
}

// handle stuff that can't be added together
}

class Rational : public Numeric
{
TypeDescritor Type() const;

bool IsPromotableTo(const Numeric &numeric);

virtual Numeric Promote(const Numeric &rhs) const;

virtual Numeric Add(const Numeric &rhs) const;
};

The functions in the derived class are returning an instance of that
derived class by value
so I don't get a memory leak or reference to a destructed object, but
the declared return
type is the base class. So when I return something like a Rational
through the base
type Numeric, I lose the dynamic 'Rationalness' and the returned value
is type as a Numeric.
So subsequent use of the returned value, even though the returned
value was originally
decalred as a Rational, will result in dispatching functions called on
the returned Rational
always getting serviced in the base Numeric.

I'm sure I'm doing something that's been done a million times before,
but I can't figure out a way to preserve the dynamic type information
for derived classes without returning values
by reference. However doing so can lead to memory leaks or dangling
references. Is there
a common pattern to handle this kind of thing?

Thanks,
 
J

jpalecek

Hello,

Hello,

I'm trying to build a set of classes that act as the handlers for a
simple expression parser, and i'm wondering how to preserve the
dynamic type information from derived classes. An example will help
illustrate what I have in mind...

class Numeric
{
// contains discriminated union to hold data and identify data
type

virtual TypeDescritor Type() const;

virtual bool IsPromotableTo(const Numeric &numeric);

virtual Numeric Promote(const Numeric &rhs) const;

virtual Numeric Add(const Numeric &rhs) const;

friend Numeric operator+(const Numeric &lhs, const Numeric &rhs);

}

Numeric operator+(const Numeric &lhs, const Numeric &rhs)
{
if(lhs.IsPromotableTo(rhs)){
return rhs.Add(lhs.Promote(rhs));
}
else if(rhs.IsPromotableTo(lsh)){
return lhs.Add(rhs.Promote(rhs));
}

// handle stuff that can't be added together

}

class Rational : public Numeric
{
TypeDescritor Type() const;

bool IsPromotableTo(const Numeric &numeric);

virtual Numeric Promote(const Numeric &rhs) const;

virtual Numeric Add(const Numeric &rhs) const;

};

The functions in the derived class are returning an instance of that
derived class by value
so I don't get a memory leak or reference to a destructed object, but
the declared return
type is the base class. So when I return something like a Rational
through the base
type Numeric, I lose the dynamic 'Rationalness' and the returned value
is type as a Numeric.
So subsequent use of the returned value, even though the returned
value was originally
decalred as a Rational, will result in dispatching functions called on
the returned Rational
always getting serviced in the base Numeric.

I'm sure I'm doing something that's been done a million times before,
but I can't figure out a way to preserve the dynamic type information
for derived classes without returning values
by reference. However doing so can lead to memory leaks or dangling
references. Is there
a common pattern to handle this kind of thing?

If you want run-time polymorphism, you need return by reference or
pointer of some kind. This way, you're slicing an object, which is
what you don't want.

Or you can put everything in one omnipotent class, which is not really
an OO solution.

Regards
Jiri Palecek
 
T

Thomas J. Gritzan

doomer said:
Hello,

I'm trying to build a set of classes that act as the handlers for a
simple expression parser, and i'm wondering how to preserve the
dynamic type information from derived classes. An example will help
illustrate what I have in mind...

class Numeric
{ [...]
virtual TypeDescritor Type() const;

virtual bool IsPromotableTo(const Numeric &numeric);

virtual Numeric Promote(const Numeric &rhs) const;

virtual Numeric Add(const Numeric &rhs) const;

friend Numeric operator+(const Numeric &lhs, const Numeric &rhs);
} [...]
The functions in the derived class are returning an instance of that
derived class by value
so I don't get a memory leak or reference to a destructed object, but
the declared return
type is the base class.

If you return a derived type by value, the object will be copied into a new
object with base class type. You loose all additional information stored in
the derived class. This is called slicing.

If you want polymorphism, you have to use a pointer or reference.

For eleminating the memory problem, you could use a smart pointer like
TR1's shared_ptr (also found in Boost).
 

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,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top