Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!brunix!sdm From: sdm@cs.brown.edu (Scott Meyers) Newsgroups: comp.lang.c++ Subject: Re: asking an object for its type Message-ID: <65594@brunix.UUCP> Date: 20 Feb 91 15:12:01 GMT References: <23984@netcom.COM> <1190@sheol.UUCP> <1991Feb19.000449.22255@gpu.utcs.utoronto.ca> <607@taumet.com> <65451@brunix.UUCP> <11284@pasteur.Berkeley.EDU> Sender: news@brunix.UUCP Reply-To: sdm@cs.brown.edu (Scott Meyers) Organization: Brown University Department of Computer Science Lines: 67 In article <11284@pasteur.Berkeley.EDU> jbuck@galileo.berkeley.edu (Joe Buck) writes: | In article <65451@brunix.UUCP>, sdm@cs.brown.edu (Scott Meyers) writes: | |> The bottom line is that virtual functions are wonderful things and can | |> almost always be used to achieve what you want, but there are times when | |> you truly *do* need to get type information as you run. | What do you care what the committee says? If you must have this feature, | write, in the baseclass | | virtual const char* myType() = 0; | | const char* ControlArc::myType() { return "ControlArc";} | | It is already in the language if you must have it. However, I would still | discourage you from this type of programming. | | Why? Because people will add new types of Arcs and you won't deal with | them properly. You're dealing with objects based on an exact match of | some type string instead of based on some relevant attribute that a | virtual function could return. You're wiring in a list of classes you | can handle, requiring more code rewriting as classes are added. | | But if you really want to do it, you can, so stop saying that C++ won't | give you run-time type information. It's trivial to add if you want it. The biggest problem with your approach is that for it to function correctly, every class derived from Arc *must* define the virtual function myType, but there is no way to make the compiler ensure this! So if somebody creates a new class and forgets to write the appropriate myType function, they'll inherit the inappropriate myType function, and the compiler will be as happy as can be while the code is wrong wrong wrong. If there were compiler support for getting at runtime type information, this whole maintenance/enhancement nightmare would disappear. And as you yourself point out, you often don't want only an exact type match, you're often interested in whether an object "isa" particular type, which means that it inherits from that type at some point, though perhaps not directly. Using virtual functions it is again possible to set things up so that the general predicate object.isa(typeSpecifier) works correctly, but I wouldn't call it "trivial." Furthermore, all such schemes suffer from the requirement that every class explicitly provide new information, again without any warning from a compiler if they fail to do so. By the way, this problem is very similar to that of providing support for safely casting from a base pointer to a derived pointer provided that the base pointer "really" points to a derived object. To see how "trivial" this is (especially in the case of multiple inheritance), check out how it's done in the NIH library. I read about it in The C++ Report: @ARTICLE{c++-casting, AUTHOR = {Desmond D'Souza}, TITLE = {{Inheritance, Virtual Base Classes, and Casts}}, JOURNAL = c++report, YEAR = {1990}, VOLUME = {2}, NUMBER = {7}, MONTH = {July/August} } Scott ------------------------------------------------------------------------------- What do you say to a convicted felon in Providence? "Hello, Mr. Mayor."