Topic: Is RTTI required if polymorphic constructor exists


Author: vandevod@cs.rpi.edu (David Vandevoorde)
Date: 1996/04/23
Raw View
>>>>> "RP" == Rich Paul <linguist@cyberspy.com> writes:
RP> Roman Lechtchinsky wrote:
[...]
>> Except that typeid(e).name() returns an implementation-defined
>> value which ( if my reading of the April DWP is correct ) is not
>> necessarily a null-terminated string. It might even be an invalid
>> pointer so that the above function wouldn't work at all. I don't
>> know if this has already been done but if not - why not guarantee
>> that the pointer is at least valid?

RP> Good lord!  Well, so much for the one purpose I used RTTI for
RP> ... anyone else have a thought on it?

I mentioned this issue in one of the C++ groups some time ago and
someone (I believe it was an ANSI X3J16 member) told me it was an
oversight: one should be able to rely one type_info::name() returning
a pointer to a null-terminated array of chars.

RP> Besides reinforcing my 'don't use it unless you HAVE to?' <G>

I think more pragmatically: don't use it unless there is no better
way... and that's true of any technique, I would say ;^)

 Daveed
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Rich Paul <linguist@cyberspy.com>
Date: 1996/04/22
Raw View
Roman Lechtchinsky wrote:
>
> > Since the typename of the exception carries some of the most relevent
> > information about the exception, why not use it ... of course, the
> > same thing could be done with virtual functions.
> >
>
> Except that typeid(e).name() returns an implementation-defined value which (
> if my reading of the April DWP is correct ) is not necessarily a
> null-terminated string. It might even be an invalid pointer so that the above
> function wouldn't work at all. I don't know if this has already been done but
> if not - why not guarantee that the pointer is at least valid?
>

Good lord!  Well, so much for the one purpose I used RTTI for ... anyone else have
a thought on it?

Besides reinforcing my 'don't use it unless you HAVE to?' <G>

--
#include <legalbs/standarddisclaimer>
Rich Paul                |  If you like what I say, tell my
C++, OOD, OOA, OOP,      |  employer, but if you don't,
OOPs, I forgot one ...   |  don't blame them.  ;->
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Roman Lechtchinsky <wolfro@cs.tu-berlin.de>
Date: 1996/04/22
Raw View
Rich Paul wrote:
>
> Roman Lechtchinsky wrote:
> >
> > > Since the typename of the exception carries some of the most relevent
> > > information about the exception, why not use it ... of course, the
> > > same thing could be done with virtual functions.
> > >
> >
> > Except that typeid(e).name() returns an implementation-defined value which (
> > if my reading of the April DWP is correct ) is not necessarily a
> > null-terminated string. It might even be an invalid pointer so that the above
> > function wouldn't work at all. I don't know if this has already been done but
> > if not - why not guarantee that the pointer is at least valid?
> >
>
> Good lord!  Well, so much for the one purpose I used RTTI for ... anyone else have
> a thought on it?
>

Actually, I've taken a closer look at the DWP. There are only two functions
which return an implementation-defined char *. First there is 'what' declared
virtual in exception and overridden in derived classes. exception::what
returns an "implementation-defined NTBS" which means that it can be used.
bad_typeid::what, bad_cast::what and bad_alloc::what return an
implementation-defined value. This is clearly an oversight. Then, there is
typeid::name which returns an implementation-defined value. I'm not sure if
this implies that this function cannot be called at all ( an invalid pointer
may not be used in an expression ). However, with this definition the
function is useless. Looks like another oversight to me.

Bye

Roman


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: satrajit@iscs.nus.sg (Satrajit Sujit Ghosh)
Date: 1996/04/17
Raw View
Fergus Henderson (fjh@munta.cs.mu.OZ.AU) wrote:
: No, RTTI is not really necessary.  `if', `while', and `for' are not
: really necessary either, because you can just use `goto'.  Like many
: other things, RTTI is not strictly necessary, but convenient.

 Would it be possible to illustrate efficient, convenient and
pratical use of the RTTI functions?

--
Satra[jit]
------------------------------------------------------
http://www.iscs.nus.sg/~satrajit
Department of Information Systems and Computer Science
National University of Singapore
======================================================

[ moderator's note: C++ programming techniques do not normally
  belong in this newsgroup -- they belong in comp.lang.c++ or
  comp.lang.c++.moderated -- but since RTTI is a new feature not
  yet widely supported, I'm allowing this question. -sdc
]


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Rich Paul <linguist@cyberspy.com>
Date: 1996/04/17
Raw View
Satrajit Sujit Ghosh wrote:
>
>         Would it be possible to illustrate efficient, convenient and
> pratical use of the RTTI functions?
>

Hmmm ... well, this comes in handy:

ostream &operator << ( ostream &os, const exception &e )
{
 return os << endl
    << "Exception: " << typeid(e).name() << endl
           << "Message:   " << e.what() << endl;
};

Since the typename of the exception carries some of the most relevent
information about the exception, why not use it ... of course, the
same thing could be done with virtual functions.

The rule of thumb I've been told is not to use RTTI unless there's
just no other way to do it.


--
#include <legalbs/standarddisclaimer>
Rich Paul                |  If you like what I say, tell my
C++, OOD, OOA, OOP,      |  employer, but if you don't,
OOPs, I forgot one ...   |  don't blame them.  ;->
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Roman Lechtchinsky <wolfro@cs.tu-berlin.de>
Date: 1996/04/18
Raw View
Rich Paul wrote:
>
> Satrajit Sujit Ghosh wrote:
> >
> >         Would it be possible to illustrate efficient, convenient and
> > pratical use of the RTTI functions?
> >
>
> Hmmm ... well, this comes in handy:
>
> ostream &operator << ( ostream &os, const exception &e )
> {
>         return os << endl
>                   << "Exception: " << typeid(e).name() << endl
>                   << "Message:   " << e.what() << endl;
> };
>
> Since the typename of the exception carries some of the most relevent
> information about the exception, why not use it ... of course, the
> same thing could be done with virtual functions.
>

Except that typeid(e).name() returns an implementation-defined value which (
if my reading of the April DWP is correct ) is not necessarily a
null-terminated string. It might even be an invalid pointer so that the above
function wouldn't work at all. I don't know if this has already been done but
if not - why not guarantee that the pointer is at least valid?

Bye

Roman
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: abell@mindspring.com (Andrew Bell)
Date: 1996/04/19
Raw View
satrajit@iscs.nus.sg (Satrajit Sujit Ghosh) wrote:
> If a polymorphic constructor can be created as demonstrated below,
>is RTTI really necessary, considering that it does not really provide a
>great deal of information.

I don't understand particularly how your sample code makes RTTI less
useful.  One place RTTI is handy is if you have an interaction between
two classes, where knowing the exact type of each class can lead to
optimizations.

For example, you might have a generic bitmap class, which returns an
RGB value for each pixel, and you want to copy one bitmap to another.
A derived class from your bitmap class might be a class that
represents a 256 color bitmap, with an overloaded copy operator.  If
you leave the bitmap you're copying as the generic type, then you need
to obtain the RGB value for a pixel, find the closest match in your
palette, and assign the pixel that palette index.  But if you know the
bitmap you're copying from is also a 256 color bitmap, you can build a
conversion table between matching palette indices, and do a much
faster copy.*

One problem, though, is that you may not care about the actual class
of an object, but just whether it is derived from (or is) of a
particular class, and RTTI doesn't help you there.

Andrew Bell
abell@mindspring.com

* For real quality, you want to dither your data, and thus this
algorithm wouldn't hold.





[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: jason@cygnus.com (Jason Merrill)
Date: 1996/04/19
Raw View
>>>>> Andrew Bell <abell@mindspring.com> writes:

> One problem, though, is that you may not care about the actual class
> of an object, but just whether it is derived from (or is) of a
> particular class, and RTTI doesn't help you there.

Why do you say that?  That's precisely what dynamic_cast is for.


...

  typedef class_where_method_is_introduced T;
  if (T* p = dynamic_cast<T*>(generic_ptr))
    {
      p->method ();
    }

...

Jason


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: satrajit@iscs.nus.sg (Satrajit Sujit Ghosh)
Date: 1996/04/14
Raw View
Hi,
 If a polymorphic constructor can be created as demonstrated below,
is RTTI really necessary, considering that it does not really provide a
great deal of information.

--
Satra[jit]
------------------------------------------------------
http://www.iscs.nus.sg/~satrajit
Department of Information Systems and Computer Science
National University of Singapore
======================================================
/*
/////////////////THE POLYMORPHIC CONSTRUCTOR///////////////////
The following code segments demonstrate the creation of a polymorphic
constructor.
///////////////////////////////////////////////////////////////
*/

#include <iostream.h>
#include <string.h>

template<class T>
class Clist{
public:
  Clist(){
    i = 0;
  };

  void insert(char *name,T *(*func)()){
    for(int j=0;j<i;j++)
      // prevent re-registration
      if (!strcmp(nm_arr[j],name)){
 return;
      }

    nm_arr[i] = strdup(name);
    fun[i] = func;
    i++;
  }

  T* get(char *name){
    int j;
    for(j=0;j<i;j++)
      if (!strcmp(nm_arr[j],name)){
 return (*fun[j])();
      }
    return NULL;
  };

  // currently can support 5 derived classes
  char *nm_arr[5];
  T *(* fun[5])();
  int i;
};



class CShape{
public:
  virtual void print(){
    cout << "reg" << endl;
  };

  static CShape * mk_subclass(char *str){
    return reg.get(str);
  }

protected:
  static int reg_sub(char *name,CShape *(*func)()){
    reg.insert(name,func);
    return 0;
  };

private:
  static Clist<CShape> reg;

};

Clist<CShape> CShape::reg;

class CCircle:public virtual CShape{
public:
  virtual void print(){
    cout <<"CCircle";
  };

  static CShape* int_new(){
    CShape *p = new CCircle;
    return p;
  };
private:
  static int i;
};

int CCircle::i = reg_sub("CCircle",&CCircle::int_new);

class CRect:public virtual CShape{
public:

  virtual void print(){
    cout <<"CRect";
  };

  static CShape* int_new(){
    CShape *p = new CRect;
    return p;
  };

private:
  static int i;
};

int CRect::i =  reg_sub("CRect",&CRect::int_new);

class CSquare:public virtual CRect{
public:

  virtual void print(){
    cout <<"CSquare";
  };

  static CShape* int_new(){
    CShape *p = new CSquare;
    return p;
  };

private:
  static int i;
};

int CSquare::i =  reg_sub("CSquare",&CSquare::int_new);


int
main(){
  CShape *fg = CShape::mk_subclass("CCircle");
  cout << "Testing constructed CCircle [";
  fg->print();
  cout << "]\n";
  CShape *fg1 = CShape::mk_subclass("CRect");
  cout << "Testing constructed CRect [";
  fg1->print();
  cout << "]\n";
  CShape *fg2 = CShape::mk_subclass("CSquare");
  cout << "Testing constructed CSquare [";
  fg2->print();
  cout << "]\n";
  return 0;
}
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1996/04/15
Raw View
satrajit@iscs.nus.sg (Satrajit Sujit Ghosh) writes:

> If a polymorphic constructor can be created as demonstrated below,
>is RTTI really necessary, considering that it does not really provide a
>great deal of information.

No, RTTI is not really necessary.  `if', `while', and `for' are not
really necessary either, because you can just use `goto'.  Like many
other things, RTTI is not strictly necessary, but convenient.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]