C++ dynamic_cast a template class to another template - c++

I am working with template class A<widget_type> and I want to know if it is possible to dynamic_cast<A<another_type>*>(A<widget_type>*).
Question: in the following code, A<B>* target2 = dynamic_cast<A<B>*>(&source); returns a null pointer. Is it possible to cast a template class into the same class but with another template?
Edit: I have to make a program where an array holds A<B*> objects, but A<B*> objects may come from A<C*> or A<D*>. I need to check at run-time if the A<B*> can be casted into the desired template class. I can't use strong-typing for that reason, since A<B*> object may come from an A<E*> object, where E is a class that other people may create and thus, there may not be a conversion function into that template class.
Code:
template<typename widget_type>
class A
{
public:
std::vector<widget_type*> value;
virtual ~A() {}
void Add(widget_type* val)
{
value.push_back(val);
}
template<typename return_type>
operator A<return_type>()
{
unsigned int size = this->value.size();
std::vector<return_type*> return_value;
return_value.resize(size);
for (unsigned int i = 0; i < size; i++)
{
return_value[i] = dynamic_cast<return_type*>(this->value[i]);
}
A<return_type> target;
target.value = return_value;
return target;
}
};
class B
{
public:
virtual ~B() {}
};
class C : public B
{
public:
void Print()
{
std::cout << "C CALL\n";
}
};
class D : public B
{
};
int main()
{
std::cout << "Start!\n";
A<C> source;
C* val1 = new C;
source.Add(val1);
A<B> target = source;
A<B>* target2 = dynamic_cast<A<B>*>(&source);
if (target2)
{
std::cout << "POINTER\n";
}
std::cout << "END\n";
}```

dynamic_cast will only succeed if there is some kind of inheritance relation between where you are coming from and where you are going to.
If you simply want to treat a pointer of one type as a pointer to a different type (which in general is true of different specializations of the same template) then dynamic_cast will not succeed. Only a c-style or reinterpret_cast will allow the cast but even then the results are not defined.

Related

Is it possible to pass "this" by default?

Is it possible to pass this by default ?
Here is what I currently have
class A
{
public:
template<typename T>
void dowithT(T t) {}
};
class B
{
public:
A a;
B()
{
//Calling 'dowithT' with 'this'
a.dowithT(this);
}
};
This function requires passing this from the caller of the function every time. So I wondered if there is a way to encapsulate this task, so that you don't need to pass this to dowithT.
I tried to do something like this:
class A
{
public:
// '= this' doesn't compile
template<typename T>
void dowithT(T t = this) {}
};
class B
{
public:
A a;
B()
{
//Calling 'dowithT' without 'this'
a.dowithT();
}
};
Unfortunately, I can't use templates, so my first solution isn't an option.
Is this possible?
Edit: I gave a concrete answer with my own implementation below. Also with a few mor deatils of what I wanted in the end.
TL;DR No, this is not possible.
this is not the same type in every class, you can't generalize it, so no, not possible.
Additionally, what would this be if doWithT() was called from a non-member function? nullptr?
That's why it isn't possible. You have to use a template.
Instead of B having a member of type A, it can inherit from A, and use something like the "curiously recurring template pattern."
If you cannot make class A a template, you can still do it like so:
class A
{
protected:
template <class T>
void dowithT()
{
T* callerthis = static_cast<T*>(this);
// callerthis is the "this" pointer for the inheriting object
cout << "Foo";
}
};
class B : public A
{
public:
B()
{
dowithT<B>();
// Or A::dowithT<B>();
}
};
dowithT() must only be called by an inheriting class (hence I made it protected), with the template parameter the caller's own type, or you'll break everything.
You may achieve exactly what you want by using a private mixin class to provide the dowithT method that takes no arguments:
#include <iostream>
#include <typeinfo>
class A
{
public:
template<typename T>
void dowithT(T* t) {
std::cout << "Hello, World" << typeid(*t).name() << std::endl;
}
};
template<class Owner>
struct calls_a
{
void dowithT()
{
auto p = static_cast<Owner*>(this);
p->a.dowithT(p);
}
};
class B
: private calls_a<B>
{
friend calls_a<B>;
A a;
public:
B()
{
//Calling 'dowithT' with 'this'
dowithT();
}
};
int main()
{
B b;
}
No, it is not possible. There is nothing really special about this when used as an argument to a function taking T* (template or not), it's just a pointer like any other.
this A is different from this B. In your first code, this refers to the caller, while in the second this refers to the callee. Thus what you want to do isnt really possible.
Here's one possibility, which might, or might not suit your needs:
template<typename T>
class A
{
public:
A(T t) : t(t) {}
void dowithT()
{
cout << "Foo";
}
private:
T t;
};
class B
{
public:
A<B*> a;
B() : a(this)
{
a.dowithT();
}
};
You could use a private method in class B that acts as a relay, and use the constant nullptr as a special value for this, if you want to be able to pass other values:
class B
{
public:
A a;
B()
{
//Calling 'dowithT' with 'this'
innerdo();
}
private:
void innerdo(B *p = nullptr) {
if (p == nullptr) p = this;
a.dowithT(p);
}
};
If you only need to pass this it is even simpler
void innerdo() {
a.dowithT(this);
}
After trying out various things you mentioned, I'd like to give my answer/solution to the problem myself to clarify some details:
#include <iostream>
using namespace std;
#include <functional>
template <typename CallerType>
class AFunctionConstructor{
private:
virtual void abstr()
{}
public:
typedef void(CallerType::*CallerTypeFunc)();
function<void()>* constructFunction(CallerTypeFunc func)
{
CallerType* newMe = dynamic_cast<CallerType*> (this);
return new function<void()>(std::bind(func,newMe));
}
};
class A : public function<void()>
{
protected:
public:
A();
A(function<void()>* func) : function<void()>(*func)
{}
};
// now create ressource classes
// they provide functions to be called via an object of class A
class B : public AFunctionConstructor<B>
{
void foo()
{
cout << "Foo";
}
public:
A a;
B() : a(constructFunction(&B::foo)) {}
};
class C : public AFunctionConstructor < C >
{
void bar()
{
cout << "Bar";
}
public:
A a;
C() : a(constructFunction(&C::bar)) {}
};
int main()
{
B b;
C c;
b.a();
c.a();
cout << endl;
A* array[5];
array[0] = &b.a; //different functions with their ressources
array[1] = &c.a;
array[2] = &b.a;
array[3] = &c.a;
array[4] = &c.a;
for (int i = 0; i < 5; i++) //this usability i wanted to provide
{
(*(array[i]))();
}
getchar();
return 0;
}
Output :
FooBar
FooBarFooBarBar
This is as far as i can press it down concerning examples. But i guess this is unsafe code. I stumbled across possible other and simpler ways to achieve this (other uses of std::function and lambdas(which i might have tried to reinvent here partially it seems)).
At first I had tried to pass "this" to the bind function in function<void()>*AFunctionConstructor::constructFunction(CallerTypeFunc func)
,though, which i now get through the dynamic upcast.
Additionally the functionality of AFunctionConstructor was first supposed to be implemented in a Constructor of A.

Insert function pointer into map with polymorphic return type

I didn't know exactly how to title this question. I have a base class and two inheriting classes:
class Base {};
class Action : public Base {};
class Title : public Base {};
Now let's say I have two functions that return either Action * or Title *:
Action *getAction() { return new Action; }
Title *getTitle() { return new Title; }
Is there any way to put these two functions into a map? Like so:
int main()
{
std::map<std::string, Base *(*)()> myMap;
myMap["action"] = getAction;
myMap["title"] = getTitle;
return 0;
}
Right now I'm getting an error:
invalid conversion from `Action* (*)()' to `Base* (*)()'
I could change the signature of the functions to always return the base class, and then it would work, but I'm wondering if there is another way to get around this.
If you use:
Base *getAction() { return static_cast<Base *>(new Action); }
Base *getTitle() { return static_cast<Base *>(new Title); }
then you will not get this error.
std::function is a polymorphic function pointer wrapper provided by the STL.
Of course, using templates, you could write your own function wrapper that stores a target, passes forward arguments and does conversion. This has already been done though, and you should seriously consider carefully before you decide to roll your own. Unless you enjoy reinventing wheels or have very special requirements.
As a proof of concept I have this code:
#include <iostream>
#include <map>
#include <functional>
struct A
{
virtual void f() = 0;
};
struct B : public A
{
void f() { std::cout << "B::f\n"; }
};
struct C : public A
{
void f() { std::cout << "C::f\n"; }
};
B* getB() { return new B; }
C* getC() { return new C; }
int main()
{
std::map<std::string, std::function<A*()>> m;
m["b"] = getB;
m["c"] = getC;
m["b"]()->f();
m["c"]()->f();
}
It leaks memory, but it works.

(re)implement dynamic_cast

I am working in an ARM7 embedded environment. The compiler I am using does not support the full C++ functionality. One feature it does NOT support is dynamic type casting.
Is there a way to implement dynamic_cast<>()?
I looked for code using Google, but no luck so far. Any ideas? Any links?
UPDATE:
Due to the comments... I'm using the ARM(R) IAR C/C++ Compiler.
dynamic_cast is useful when casting away from the base class, something to be done as little as possible.
Assuming the instances when you want to do this are limited, then a virtual function like GetMessageType() in a base class returning a different value in each derived class will let you know what to static_cast down to.
Take a look at the COM concepts -- objects there have a method to return a pointer to a specific interface that is selected by an identifier not built into the compiler (in COM's case, a UUID).
Depending on your application, a simple integer may do:
class castable {
virtual bool cast_to(int desttype) = 0;
};
class type1 : public castable { public: static int const type = 1; };
class type2 : public castable { public: static int const type = 2; };
class impl : public type1, public type2 {
virtual void *cast_to(int desttype) {
switch(desttype) {
case type1::type: return static_cast<type1 *>(this);
case type2::type: return static_cast<type2 *>(this);
default: return 0;
}
}
};
Then, if templates work correctly:
template<typename T> T my_dynamic_cast(castable *obj) {
return reinterpret_cast<T>(obj.cast_to(T::type));
}
You can then create objects normally, and cast between base class pointers:
impl im;
type1 *t1 = &im; // Implicit, as it is a base class
type2 *t2 = my_dynamic_cast<type2 *>(t1);
The only difficulty here is assigning the identifiers.
It really depends exactly how much of dynamic_cast functionality you need.
Most often, I see dynamic_cast used to perform a checked conversion: dynamic_cast<Derived*>(p) will return 0 if ultimately p real type is not Derived*...
... but even this is quite complicated:
What if p is really EvenMoreDerived and not just Derived ?
What is p inherits from Base multiple times ?
And it can get even more hairy:
static_cast is not able to cross virtual inheritance boundaries.
static_cast is not suitable for cross-branches conversions (you have to pass through the common ancestor)
static_cast cannot emulate the dynamic_cast<void*>() conversion.
So, if you want a simple barebone functionality of checked conversion up the inheritance tree in case of single inheritance without virtual thrown in, then you can actually implement it in user-land.
Otherwise, without RTTI support, you will be quite stuck.
Example of simple (dumb ?) implementation, beginning with the support from the class hierarchy:
class Base {
public:
typedef size_t ID;
virtual ID getID() const = 0;
protected:
static ID NextID() { static ID = 0; return ID++; }
// much more stuff
};
class Derived: public Base {
public:
static ID GetID() { static ID id = Base::NextID(); return id; }
virtual ID getID() const { return GetID(); }
};
We can leverage this with:
template <typename To>
To* dyn_cast(Base* b) {
if (b and b->getID() == To::GetID()) { return static_cast<To*>(b); }
return 0;
}
However, this only work for one level. So, if MoreDerived inherits from Derived then:
MoreDerived md;
assert(dyn_cast<Derived>(&md)); // failure ...
so it really gets tricky here.
A possible approach is to check from the top of the hierarchy, to the bottom.
class Base {
public:
template <typename To>
bool isa() const {
return this->match(To::GetID());
}
protected:
typedef size_t ID;
static ID NextID() { static ID id = 0; return id++; }
virtual bool match(ID) const { return false; }
};
class Derived: public Base {
public:
static ID GetID() { static ID id = NextID(); return id; }
protected:
virtual bool match(ID id) const { return id == GetID() || Base::match(id); }
};
class MostDerived: public Derived {
public:
static ID GetID() { static ID id = NextID(); return id; }
protected:
virtual bool match(ID id) const { return id == GetID() || Derived::match(id); }
};
Slightly more complex, but now:
template <typename To, typename From>
To const* dyn_cast(From const* f) {
if (f and f->template isa<To>()) { return static_cast<To const*>(f); }
return 0;
}
template <typename To, typename From>
To* dyn_cast(From* f) { return const_cast<To*>(dyn_cast<To>((From const*)f)); }
Test case:
int main() {
Derived derived; MostDerived mostDerived;
Base* d = &derived, * md = &mostDerived;
if (dyn_cast<Derived>(d)) { std::cout << "Derived -> Derived: ok\n"; }
else { std::cout << "Derived -> Derived: ko\n"; }
if (dyn_cast<MostDerived>(md)) { std::cout << "MostDerived -> MostDerived : ok\n"; }
else { std::cout << "MostDerived -> MostDerived : ko\n"; }
if (dyn_cast<Derived>(md)) { std::cout << "MostDerived -> Derived : ok\n"; }
else { std::cout << "MostDerived -> Derived : ko\n"; }
if (dyn_cast<MostDerived>(d)) { std::cout << "Derived -> MostDerived: ko\n"; }
else { std::cout << "Derived -> MostDerived: ok\n"; }
}
In action at ideone.
It is still very incomplete compared to a true dynamic_cast though. But it should cover most uses already.
Isn't it possible to just cast your pointer and start using it as the other type of object?
Foo* f = new Foo();
f.baz();
Bar* b = (Bar*)f;
b.bop();

Determining size of a polymorphic C++ class

Using the sizeof operator, I can determine the size of any type – but how can I dynamically determine the size of a polymorphic class at runtime?
For example, I have a pointer to an Animal, and I want to get the size of the actual object it points to, which will be different if it is a Cat or a Dog. Is there a simple way to do this, short of creating a virtual method Animal::size and overloading it to return the sizeof of each specific type?
If you know the set of possible types, you can use RTTI to find out the dynamic type by doing dynamic_cast. If you don't, the only way is through a virtual function.
Or you can use typeid, which might be faster than dynamic_cast (also with dynamic_cast you can cast to intermediary types in the hierarchy).
It looks rather bad:
#include <iostream>
#include <typeinfo>
class Creature
{
char x[4];
public:
virtual ~Creature() {}
};
class Animal: public Creature { char x[8];};
class Bird: public Creature { char x[16]; };
class Dog: public Animal { char x[32]; };
class Cat: public Animal { char x[64]; };
class Parrot: public Bird { char x[128]; };
unsigned creature_size(const Creature& cr)
{
if (typeid(cr) == typeid(Animal)) {
return sizeof (Animal);
}
else if (typeid(cr) == typeid(Dog)) {
return sizeof(Dog);
}
else if (typeid(cr) == typeid(Cat)) {
return sizeof(Cat);
}
else if (typeid(cr) == typeid(Bird)) {
return sizeof(Bird);
}
else if (typeid(cr) == typeid(Parrot)) {
return sizeof(Parrot);
}
else if (typeid(cr) == typeid(Creature)){
return sizeof(Creature);
}
assert(false && "creature_size not implemented for this type");
return 0;
}
int main()
{
std::cout << creature_size(Creature()) << '\n'
<< creature_size(Animal()) << '\n'
<< creature_size(Bird()) << '\n'
<< creature_size(Dog()) << '\n'
<< creature_size(Cat()) << '\n'
<< creature_size(Parrot()) << '\n' ;
}
For each new type you'll need to add code to the creature_size function. With a virtual size function you'll need to implement this function in each class as well. However, this function will be significantly simpler (perfectly copy-n-pasteable, which shows there might be both a limitation in the language and a problem with your code design):
virtual unsigned size() const { return sizeof(*this); }
And you can make it abstract in the base class which means that it will be a compiler error if you forget to override this method.
Edit: this is naturally assuming that given any Creature you want to know its size. If you have a strong reason to believe that you are dealing with a Dog - or a subclass of Dog (and you don't care if it is a subclass), then naturally you can use dynamic_cast for an ad hoc test.
If you are able to change source classes' design, you can totally replace dynamic polymorphism (which uses virtual functions) with static polymorphism and use the CRTP idiom:
template <class TDerived>
class Base
{
public:
int getSize()
{ return sizeof(TDerived); }
void print()
{
std::cout
<< static_cast<TDerived*>(this)->getSize()
<< std::endl;
}
int some_data;
};
class Derived : public Base<Derived>
{
public:
int some_other_data1;
int some_other_data2;
};
class AnotherDerived : public Base<AnotherDerived>
{
public:
int getSize()
{ return some_unusual_calculations(); }
// Note that the static_cast above is required for this override to work,
// because we are not using virtual functions
};
int main()
{
Derived d;
d.print();
AnotherDerived ad;
ad.print();
return 0;
}
You can do this when the needed polymorphic behavior of program can be determined at compile-time (like the sizeof case), since the CRTP has not the flexibility of dynamic polymorphism to resolve the desired object at run-time.
The static polymorphism also has the advantage of higher performance by removing virtual-function-call overhead.
If you don't want to templatize Base class or you need to hold different derived instances of Base class in a same location (like an array or a vector), you can use CRTP on a middle class and move the polymorphic behavior to that class (similar to the Polymorphic copy construction example in the Wikipedia):
class Base
{
public:
virtual int getSize() = 0;
void print()
{
std::cout << getSize() << std:endl;
}
int some_data;
};
template <class TDerived>
class BaseCRTP: public Base
{
public:
virtual int getSize()
{ return sizeof(TDerived); }
};
class Derived : public BaseCRTP<Derived>
{
// As before ...
};
class AnotherDerived : public BaseCRTP<AnotherDerived>
{
// As before ...
// Note that although no static_cast is used in print(),
// the getSize() override still works due to virtual function.
};
Base* obj_list1[100];
obj_list1[0] = new Derived();
obj_list1[2] = new AnotherDerived();
std::vector<Base*> obj_list2;
obj_list2.push_back(new Derived());
obj_list2.push_back(new AnotherDerived());
--
Update: I now found a similar but more detailed answer on stackoverflow which explains that if we further derive from the derived classes above (e.g. class FurtherDerived : public Derived {...}), the sizeof will not report correctly. He gives a more complex variant of the code to overcome this.
I can't believe that somebody's invented type_id() instead of implementing proper traits ....
One slightly convoluted way that will also work is to implement this through a Curiously Recurring Template Pattern
#include <iostream>
class Base {
public:
virtual ~Base() {}
virtual size_t getSize() = 0;
};
template <class T>
class BaseT : public Base {
public:
size_t getSize() override { return sizeof(T); }
};
class Child : public BaseT<Child> {};
int main()
{
std::unique_ptr<Base> child(new Child);
std::cout << child->getSize();
}

How do I check if an object's type is a particular subclass in C++?

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)
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) == nullptr)
{
std::cout << "NOT A D2" << std::endl;
}
if (dynamic_cast<D1*>(x) == nullptr)
{
std::cout << "NOT A D1" << std::endl;
}
}
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();
}
Edit: Since the debate about this answer still goes on after so many years, I thought I should throw in some references. If you have a pointer or reference to a base class, and your code needs to know the derived class of the object, then it violates Liskov substitution principle. Uncle Bob calls this an "anathema to Object Oriented Design".
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) != nullptr;
}
The code below demonstrates 3 different ways of doing it:
virtual function
typeid
dynamic_cast
#include <iostream>
#include <typeinfo>
#include <typeindex>
enum class Type {Base, A, B};
class Base {
public:
virtual ~Base() = default;
virtual Type type() const {
return Type::Base;
}
};
class A : public Base {
Type type() const override {
return Type::A;
}
};
class B : public Base {
Type type() const override {
return Type::B;
}
};
int main()
{
const char *typemsg;
A a;
B b;
Base *base = &a; // = &b; !!!!!!!!!!!!!!!!!
Base &bbb = *base;
// below you can replace base with &bbb and get the same results
// USING virtual function
// ======================
// classes need to be in your control
switch(base->type()) {
case Type::A:
typemsg = "type A";
break;
case Type::B:
typemsg = "type B";
break;
default:
typemsg = "unknown";
}
std::cout << typemsg << std::endl;
// USING typeid
// ======================
// needs RTTI. under gcc, avoid -fno-rtti
std::type_index ti(typeid(*base));
if (ti == std::type_index(typeid(A))) {
typemsg = "type A";
} else if (ti == std::type_index(typeid(B))) {
typemsg = "type B";
} else {
typemsg = "unknown";
}
std::cout << typemsg << std::endl;
// USING dynamic_cast
// ======================
// needs RTTI. under gcc, avoid -fno-rtti
if (dynamic_cast</*const*/ A*>(base)) {
typemsg = "type A";
} else if (dynamic_cast</*const*/ B*>(base)) {
typemsg = "type B";
} else {
typemsg = "unknown";
}
std::cout << typemsg << std::endl;
}
The program above prints this:
type A
type A
type 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).
I don't know if I understand your problem correctly, so 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! Okay, 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 header TypeManip.h from it in your source code then use the SuperSubclass class template as follows:
if(SuperSubClass<B,D>::value)
{
...
}
According to documentation, SuperSubClass<B,D>::value will be true if B is a public base of D, or if B and D are aliases of the same type.
i.e. 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<B,D>::value happens at compile time unlike some methods which use dynamic_cast, hence there is no penalty for using this system at runtime.
I disagree that you should never want to check an object's type in C++. If you can avoid it, I agree that you should. Saying you should NEVER do this under any circumstance is going too far though. You can do this in a great many languages, and it can make your life a lot easier. Howard Pinsley, for instance, showed us how in his post on C#.
I do a lot of work with the Qt Framework. In general, I model what I do after the way they do things (at least when working in their framework). The QObject class is the base class of all Qt objects. That class has the functions isWidgetType() and isWindowType() as a quick subclass check. So why not be able to check your own derived classes, which is comparable in it's nature? Here is a QObject spin off of some of these other posts:
class MyQObject : public QObject
{
public:
MyQObject( QObject *parent = 0 ) : QObject( parent ){}
~MyQObject(){}
static bool isThisType( const QObject *qObj )
{ return ( dynamic_cast<const MyQObject*>(qObj) != NULL ); }
};
And then when you are passing around a pointer to a QObject, you can check if it points to your derived class by calling the static member function:
if( MyQObject::isThisType( qObjPtr ) ) qDebug() << "This is a MyQObject!";
#include <stdio.h>
#include <iostream.h>
class Base
{
public: virtual ~Base() {}
template<typename T>
bool isA() {
return (dynamic_cast<T*>(this) != NULL);
}
};
class D1: public Base {};
class D2: public Base {};
class D22: public D2 {};
int main(int argc,char* argv[]);
{
D1* d1 = new D1();
D2* d2 = new D2();
D22* d22 = new D22();
Base* x = d22;
if( x->isA<D22>() )
{
std::cout << "IS A D22" << std::endl;
}
if( x->isA<D2>() )
{
std::cout << "IS A D2" << std::endl;
}
if( x->isA<D1>() )
{
std::cout << "IS A D1" << std::endl;
}
if(x->isA<Base>() )
{
std::cout << "IS A Base" << std::endl;
}
}
Result:
IS A D22
IS A D2
IS A Base
I was thinking along the lines of using typeid()...
Well, yes, it could be done by comparing: typeid().name(). If we take the already described situation, where:
class Base;
class A : public Base {...};
class B : public Base {...};
void foo(Base *p)
{
if(/* p is A */) /* do X */
else /* do Y */
}
A possible implementation of foo(Base *p) would be:
#include <typeinfo>
void foo(Base *p)
{
if(typeid(*p) == typeid(A))
{
// the pointer is pointing to the derived class A
}
else if (typeid(*p).name() == typeid(B).name())
{
// the pointer is pointing to the derived class B
}
}
I see some good answers here and I see some dumb response.
"Trying to query the type of an object is a design flaw". Which means that Java instanceof and C# is keywords are design flaws. These are response of people that dont rate polymorphism. If you have an interface, that interface is derived by another interface that impelments more features. If you need these extra features you must first check that you have such an interface. Even microsoft COM API makes use of this design.
Then in terms of how to deduce if an object is a instanceof a class, many good answers have already been given
typeid
having a virtual type function
dynamic cast
is_base_of has nothing to do with polymorphism.
And having each virtual function define its own type method is unnecessary as it is redundant. Each virtual class already has a pointer to its virtual table.
class Base
{
void *p_virtual_table = BASE_VIRTUAL_TABLE;
}
class Derived : Base
{
void *p_virtual_table = DERIVED_VIRTUAL_TABLE;
}
void *BASE_VIRTUAL_TABLE[n];
void *DERIVED_VIRTUAL_TABLE[n];
The point here is that the address of the virtual tables are fixed and a simple comparrison will decide if a virtual object is an instanceof a virtual class.
Since cpp doesnt give us a standard way of accessing the virtual tables, it would be hard to do these comparrisons manually. But the cpp abstract machine has absolutely no problems deducing the exact instance of a virtual object.
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
You can do it with templates (or SFINAE (Substitution Failure Is Not An Error)). Example:
#include <iostream>
class base
{
public:
virtual ~base() = default;
};
template <
class type,
class = decltype(
static_cast<base*>(static_cast<type*>(0))
)
>
bool check(type)
{
return true;
}
bool check(...)
{
return false;
}
class child : public base
{
public:
virtual ~child() = default;
};
class grandchild : public child {};
int main()
{
std::cout << std::boolalpha;
std::cout << "base: " << check(base()) << '\n';
std::cout << "child: " << check(child()) << '\n';
std::cout << "grandchild: " << check(grandchild()) << '\n';
std::cout << "int: " << check(int()) << '\n';
std::cout << std::flush;
}
Output:
base: true
child: true
grandchild: true
int: false
As a spin off of multiple other answers (including one I previously posted myself!), here's a macro to help:
#define isInstance( ptr, clazz ) (dynamic_cast<const clazz*>(ptr) != NULL)
In c# you can simply say:
if (myObj is Car) {
}