2
  1. Would you use dynamic cast in a frequently run method? Does it have a large overhead?

  2. What exactly IS the pointer returned by dynamic_cast. A pointer to the same address? a pointer to a different instance? I lack this understanding. More in specific - There's an assignment I wish to make to a pointer of a father type only if in runtime it turns out to be a pointer to a son type. Solutions?

Thank you.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
user181218
  • 1,655
  • 5
  • 28
  • 42

5 Answers5

6

dynamic_cast helps you check the validity while performing downcasting.

It returns a NULL or throws an exception(std::bad_cast for References)if the pointer or the reference cannot be safely downcasted.

Would you use dynamic cast in a frequently run method? Does it have a large overhead? dynamic_cast does use some additional RTTI(Run Time Type Information) for determining the validity of cast. So there is an overhead for sure. Typically, a pointer to typeinfo of the type will be added to the virtual table. I say typically, because virtual mechanism itself is compiler implementation dependant detail(may vary for different compilers).

You will have to profile your code using some good profiling tools to determine if calling dynamic_cast repeatedly reduces the performance of your code.

What exactly IS the pointer returned by dynamic_cast. A pointer to the same address? a pointer to a different instance?

It is easier to understand when instead of analyzing downcasting with dynamic_cast we analyze upcasting. Given a type base and another type derived that inherits from base, the derived type will contain a subobject of type base. When a pointer to a derived object is upcasted to a pointer to base, the result of the operation will be the address of the base subobject inside derived. Performing a dynamic_cast reverts that operation, and returns a pointer to the derived object that contains a base subobject in the address passed as argument (static_cast does the same, but it will apply the possible offset without actually checking the runtime type).

In the simplest case, with single (non-virtual) inheritance the derived subobject will be aligned base, but in the event of multiple inheritance, that will not be the case:

struct base {
   int x;
   virtual void foo() {}
};
struct another_base {
   virtual void bar() {}
};
struct derived : base, another_base {};
int main() {
   derived d;
   base * b = &d;           // points to the base subobject inside derived
   another_base * o = &d;   // points to the another_base subobject inside derived

   std::cout << std::boolalpha
       << ( static_cast<void*>(b) == dynamic_cast<derived*>(b) ) << "\n"
       << ( static_cast<void*>(o) == dynamic_cast<derived*>(o) ) << std::endl;
}

The program will print true, false. Note that you have to explicitly cast one of the pointers to void* if you want to compare them, or else the compiler will perform an implicit upcast the downcasted pointer.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • Thank you for your detailed reply, and I appologize if the following question is even more stupid - I have very little experience with this: – user181218 Jun 15 '11 at 08:05
  • 2
    It does not always return the same address. There are situations where the address of the pointer has to be modified. BUT it will always point at the some part of the original object. – Martin York Jun 15 '11 at 08:16
  • 2
    The second part is not *correct* in the general case. In this particular case the two pointers are the same, but that needs not be the case. Consider, for example, taht there was a non-empty class `C`, and that `B` inherited from both `C` and `A`: `struct B : C, A`. Now the `A` subobject is not aligned with the `B` object, and the pointers to `A` and `B` will not be the same. And that is not even considering virtual inheritance... It is guaranteed that both pointers refer to the same *real* object (one being a subobject of the other) – David Rodríguez - dribeas Jun 15 '11 at 08:17
  • @David Rodríguez - dribeas: Thanks, I think that is correct. That should be added to the answer indeed. If you feel inclined and generous enough to format that with an example and add it to the answer, would be nice or perhaps I would modify it later. – Alok Save Jun 15 '11 at 08:48
  • @David Rodríguez - dribeas: Being weekend, I just about revisited the Q today, to make the answer more appropriate as per your suggestion, And whoa you already did! Thanks a lot, I wish could upvote you on that.(On a side note, I wish SO provided a alert in inbox if ones own answer was edited by someone else, that would have made me seen this update 2 days ago!) Sorry for the delay in reverting. – Alok Save Jun 18 '11 at 07:03
1

It doesn't matter if the method is "frequently run", only if running it has an important negative effect on required performance. and the only way to find that out is to profile your code.

The pointer returned is just a pointer. You need to post example code to clarify the second half of your question. If you mean this:

Base * p1 = ....;

Derived * d = dynamic_cast<Derived*>(p1);
if ( d ) {
     (*d) = "foobar";
}

Then that is fine provided Derived supports assignment.

1

Would you use dynamic cast in a frequently run method? Does it have a large overhead?

It does not have really big overhead. But it depends on compiler's implementation of RTTI. However, do not optimize prematurely.

What exactly IS the pointer returned by dynamic_cast. A pointer to the same address? a pointer to a different instance? I lack this understanding. More in specific - There's an assignment I wish to make to a pointer of a father type only if in runtime it turns out to be a pointer to a son type. Solutions?

Any object of derived class contains opjects of its base classes. dynamic_cast returns pointer to one of these objects (it is typically the same pointer when class inherits only one base class, but it is not the same pointer if class inherits more than 1 base class). But it depends on used compiler.

frp
  • 1,119
  • 1
  • 10
  • 30
0
  1. See the accepted answer for this post How to profile my C++ application on linux. It covers what options to call valgrind with and an application to view the profile results in a nice gui.

  2. dynamic cast will return a pointer of the type you casted with the same address as the argument, so it is pointing to the same object. When dynamic casting the "son" type to the "father type, dynamic cast will throw a std::bad_cast exception if the argument is not of the "son" type.

Community
  • 1
  • 1
Marty B
  • 243
  • 3
  • 10
  • Your second point is true only for references - dynamic_cast on pointers will return NULL if the cast fails. –  Jun 15 '11 at 07:49
  • Its pointing at the same object but the address does not need to be the same. – Martin York Jun 15 '11 at 08:18
0

What exactly IS the pointer returned by dynamic_cast. A pointer to the same address? a pointer to a different instance? I lack this understanding. More in specific - There's an assignment I wish to make to a pointer of a father type only if in runtime it turns out to be a pointer to a son type.

Suppose you have

class Base { ... };
class ChildA : public Base { ... };
class ChildB : public Base { ... };

ChildA childa;
ChildB childb;

Base * ptra = &childa;
Base * ptrb = &childb;

ChildA * ptra_as_ChildA = dynamic_cast<ChildA*>(ptra); // == &childa
ChildA * ptrb_as_ChildA = dynamic_cast<ChildA*>(ptrb); // == NULL

dynamic_cast will return a non-null pointer if the pointed-to object is an instance of the target class or a class that derives from the target class. It returns a null pointer if the pointed-to object is not an instance of the target class.

NOTE: The exact memory positions pointed to by the pointer input to dynamic_cast and the pointer returned by dynamic_cast may not be the same. Example: Suppose ChildA inherits from two classes, Base and SomeInterface. You can static_cast a ChildA pointer to a Base pointer and to a SomeInterface pointer. At least one of those two parent class pointers is not going to point to the same memory location as the ChildA pointer. Dynamic casting either of those two parent class pointers will return that original ChildA pointer.

David Hammen
  • 32,454
  • 9
  • 60
  • 108