views:

766

answers:

7

I was thinking along the lines of using typeid() but I don't know how to ask if that type is a subclass of another class (which, by the way, is abstract)

Edit: I should definitely mention the language, C++

A: 

In c# you can simply say

if (myObj is Car) {

}

Decker
I answered this before the poster edit-ed his question and indicated his language choice.
Decker
A: 

You can only do it at compile time using templates, unless you use RTTI.

It lets you use the typeid function which will yield a pointer to a type_info structure which contains information about the type.

Read up on it at Wikipedia

+9  A: 

You really shouldn't. If your program needs to know what class an object is, that usually indicates a design flaw. See if you can get the behavior you want using virtual functions. Also, more information about what you are trying to do would help.

I am assuming you have a situation like this


class Base;
class A : public Base {...};
class B : public Base {...};

void foo(Base *p)
{
  if(/* p is A */) /* do X */
  else /* do Y */
}

If this is what you have, then try to do something like this:


class Base
{
  virtual void bar() = 0;
};

class A : public Base
{
  void bar() {/* do X */}
};

class B : public Base
{
  void bar() {/* do Y */}
};

void foo(Base *p)
{
  p->bar();
}
Dima
+1. I think the correct name for this is "Tell, don't ask". Basically, always favour polymorphism (TELLing an object what to do, letting the implementation take care of it) over a case/if statement where you ASK to find out what type of object you are dealing with.
LeopardSkinPillBoxHat
yep - this is all good - but the guy wanted to know about how to resolve type
JohnIdol
JohnIdol, I get it. And it is still a bad idea.
Dima
+8  A: 

 

class Base
{
  public: virtual ~Base() {}
};

class D1: public Base {};

class D2: public Base {};

int main(int argc,char* argv[]);
{
  D1   d1;
  D2   d2;

  Base*  x = (argc > 2)?&d1:&d2;

  if (dynamic_cast<D2*>(x) == NULL)
  {
    std::cout << "NOT A D2" << std::endl;
  }
  if (dynamic_cast<D1*>(x) == NULL)
  {
    std::cout << "NOT A D1" << std::endl;
  }
}
Martin York
+4  A: 

You can do it with dynamic_cast (at least for polymorphic types).

Actually, on second thought--you can't tell if it is SPECIFICALLY a particular type with dynamic_cast--but you can tell if it is that type or any subclass thereof.

template <class DstType, class SrcType>
bool IsType(const SrcType* src)
{
  return dynamic_cast<const DstType*>(src) != 0;
}
Drew Hall
+2  A: 

dynamic_cast can determine if the type contains the target type anywhere in the inheritance hierarchy (yes, it's a little-known feature that if B inherits from A and C, it can turn an A* directly into a C*). typeid() can determine the exact type of the object. However, these should both be used extremely sparingly. As has been mentioned already, you should always be avoiding dynamic type identification, because it indicates a design flaw. (also, if you know the object is for sure of the target type, you can do a downcast with a static_cast. Boost offers a polymorphic_downcast that will do a downcast with dynamic_cast and assert in debug mode, and in release mode it will just use a static_cast).

coppro
A: 

I dont know if I got you problem correctly let me restate it in my own words...

Problem: Given classes B and D determine if D is a subclass of B (or vice-versa?)

Solution: Use some template magic! Ok seriously you need to take a look at LOKI an excellent template meta-programming library produced by the fabled C++ author Andrei Alexandrescu.

More specifically download LOKI and include "TypeManip,h" from it in your source code then use the SuperSubclass class template as follows

if(SuperSubClass::value) { ... }

According to documentation... SuperSubClass::value will be true if B is a public base of D, or if B and D are aliases of the same type.

ie either D is a subclass of B or D is the same as B.

I hope this helps.

edit:

Please note the evaluation of SuperSubClass::value happens at compile time unlike some methods which use dynamic_cast hence there is no penalty for using this system at runtime.

SDX2000