Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
General
GeneralPortable MacsHardwareNetworking
Applications
Mac ApplicationsEudoraFirefox / MozillaInternet ExplorerOutlook ExpressMS OfficeEntourageExcelPowerPointWordVirtual PCMedia PlayerOther MS Products
Programming
Mac ProgrammingCodeWarriorPerl
Country Specific
Australian Mac GroupUK Mac Group

Mac Forum / Programming / CodeWarrior / June 2004



Tip: Looking for answers? Try searching our database.

Basic C++ question

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Andy Bettis - 24 Jun 2004 09:55 GMT
Hi folks,

Is there an easy way to find out what type of object is referenced by a
pointer? If I have an array of objects of different types (but all
subtypes of a common parent object type) and I fetch one of them, how
can I find out what type it is? I can add a object type indicator to
each type and use an accessor function to get it, but I wondered if
there's a built-in method?

Cheers.

Rev. Andy
Jack D - 24 Jun 2004 10:37 GMT
> Is there an easy way to find out what type of object is referenced by a
> pointer? If I have an array of objects of different types (but all
> subtypes of a common parent object type) and I fetch one of them, how
> can I find out what type it is? I can add a object type indicator to
> each type and use an accessor function to get it, but I wondered if
> there's a built-in method?

You could use dynamic_cast, if you try to cast an object to a type that
it isn't, this returns null, else it returns a valid pointer. This does
oblige the compiler to maintain RTTI though, which causes some possibly
unwanted overhead.

On a side note, next time it might be better to post such questions in
comp.lang.c++.
Dave Baum - 24 Jun 2004 17:02 GMT
> Hi folks,
>
[quoted text clipped - 4 lines]
> each type and use an accessor function to get it, but I wondered if
> there's a built-in method?

There are a couple of ways to do this depending on why you need to find
out the type of the object.

If you are writing code that wants to treat one or more types
differently from the rest, then dynamic_cast is often a good choice:

class Foo
{
};

class Bar : public Foo
{
};

void myFunc(Foo *f)
{
  Bar *b = dynamic_cast<Bar*>(f);
  if (b) {
     // f points to a Bar object (or a subclass of Bar)
  }
  else {
     // f points to a Foo that is not a Bar (or subclass of Bar)
  }
}

If you find yourself using dynamic_cast a lot, then it may be a sign
that you should add some virtual methods to your base class.

If for the purposes of logging or debugging you want to know the name of
the type of the object, then you can use the typeid() operator (which
returns a reference to a type_info object):

#include <typeinfo>

void myFunc(Foo *f)
{
 cout << typeid(*f).name();
}

I believe that RTTI has to be enabled in the compiler settings for
either of these mechanisms to work with CW.

Dave
MW Ron - 24 Jun 2004 17:16 GMT
>Hi folks,
>
[quoted text clipped - 4 lines]
>each type and use an accessor function to get it, but I wondered if
>there's a built-in method?

RTTI  runtime type information is built into C++ beside dynamic_cast to
see if it is of a type there is typeid and typeinfo

Ron

Signature

 Metrowerks, one of the world¹s top 100 companies and influencers
    in the software development industry. - SD Times  May 2004
              http://www.sdtimes.com/2004sdt100.htm
     
                 Metrowerks, maker of CodeWarrior
Ron Liechty - MWRon@metrowerks.com - http://www.metrowerks.com

David Phillip Oster - 25 Jun 2004 03:33 GMT
> Is there an easy way to find out what type of object is referenced by a
> pointer? If I have an array of objects of different types (but all
> subtypes of a common parent object type) and I fetch one of them, how
> can I find out what type it is? I can add a object type indicator to
> each type and use an accessor function to get it, but I wondered if
> there's a built-in method?

That you feel you need to do this is usually a sign of bad design.
Usually you want to define some interface classes: these classes have no
parent, contain no data, have a do-nothing virtual destructor, and
define a bunch of non-virtual public member functions that just call
private virtual member functions. Then you make a consolidator root
class that just multiply inherits from a bunch of interfaces. Then you
make a container that just holds pointers to objects that inherit from
the consilidator. Clients of the container just call public member
functions of the public interface. You tell objects to do their job. How
they do it is up to them.

Here is an example from a MacDraw style vector graphics program of mine.
a Layer interface is implemented by a LayerImplementation that contains
a vector of reference-counting pointers to Shapes.

using boost::bind;
using boost::ref;
using std::find_if;
using std::mem_fun_ref;

...

/* Print - the subset of draw suitable for printing.
*/
void LayerImpl::Print(DrawContext& inContext, const PanelSpec& inPanel){
#pragma unused(inPanel)
  if(not IsEnabled()){
     return;
  }
  for_all(mShapes, bind(&ShapeInterface::Print, _1, ref(inContext)));
}

/* Draw - tell children to draw themselves (if they are visible), they'll
  check the context argument to find out.
*/
void LayerImpl::Draw(DrawContext& inContext, const PanelSpec& inPanel){
  if(not IsEnabled()){
     return;
  }
  for_all(mShapes, bind(&ShapeInterface::Draw, _1, ref(inContext)));
}

bool LayerImpl::Click(const MousePoint& inPoint, DrawContext& inContext){
  if(not IsEnabled()){
     return false;
  }
  return mShapes.rend() != find_if(
     mShapes.rbegin(),
     mShapes.rend(),
     bind(&ShapeInterface::Click, _1, ref(inPoint), ref(inContext)));
}

....

for_all is defined as:

// for_all : like for_each, but apply to all elements of a container
template<class Container, class Function>
inline Function for_all(Container &v, Function f){
  return std::for_each(v.begin(), v.end(), f);
}

and passing arguments to the member function that For_all calls is done
with boost::bind, see <http://boost.org>

Note that when processing clicking, we process the vector in reverse
order, since we want things drawn last to get a crack at the click first.

Note that this example makes heavy use of standard library container
algorithms to apply member functions (with some of the arguments bound
to actual values) to objects in the container.

I use boost's reference-counting smart pointers so I can refer to
objects in the drawing also in the multiple-undo history and on the
clipboard or in a drag, and be certain I won't either delete something
prematurely or have a memory leak.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.