dynamic_cast

why the below code is not working in dev cpp compiler?
#include<iostream>
#include<typeinfo>
using namespace std;
class A{public:
      virtual void f(){
      }
};
class B{};
class C{
};
bool check(A* ptr){B *der;
if(der=dynamic_cast<B* >()ptr)
return true;
else return false;
}
int main(){B* d1=new B;
C* d2=new C;
if(check(d1))cout<<"ok";
else
cout<<"not ok";
return 0;      
}//error: cannot convert 'B*' to 'A*' for argument '1' to 'bool check(A*)'
Ganesh SadanalaAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Fabrice LambertConsultingCommented:
Hi,

I guess it is because class A et B have nothing related to each other, thus one can't be transtyped to the other.
In other words, you're trying convert a car into a salad.

Additional notes:
You should not use raw pointers in C++, unless you are aware of all the consequences.
As it stand, even without the call to the check function, your main function is bugged and subject to memory leaks (and it isn't only because of the absence of delete statement).
ZoppoCommented:
Hi,

this is because the classes A and B are unrelated (none is derived by the other and they don't have similar base class).

For this conversion you need a reinterpret_cast< B* >( ... );

BTW: You should have a good reason to do this, because it's ugly and error prone.

Hope that helps,

ZOPPO
Fabrice LambertConsultingCommented:
According to the documentation: http://en.cppreference.com/w/cpp/language/dynamic_cast
Safely converts pointers and references to classes up, down, and sideways along the inheritance hierarchy.
Only class with inheritance relationship can be converted.
Amazon Web Services

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

sarabandeCommented:
For this conversion you need a reinterpret_cast< B* >( ... );

no, this would be a severe error if you make a cast that is definitively wrong. if class B has members (data or functions) different to A (even if they are only in different order), any usage of the wrong ly casted pointer might corrupt your heap or stack memory.

so for the first cast you need either B derived from A or vice versa. If B was derived from A the ptr must point to an object that "IS A" B object. you can't make a dynamic cast  if ptr points to a pure A object. note, a dynamic_cast would return a NULL pointer if the cast was invalid.

reinterpret_cast should be a rare thing in c++. it is necessary if you have to use an interface (mostjy c interface) which provides a void or char pointer for arguments. then the caller would put any arbitrary pointer type for the argument and when the argument was passed to a callback or thread function, the called function would use a reinterpret_cast in order to get a pointer of the original type.

main thread:

    MyClass * ptr = new MyClass(arguments);
    begin_thread(thread_function, ptr);

worker thread:

   void thread_function(void * p)
   {
         // here the function knows that the passed p is a MyClass pointer
         MyClass ptr = reinterpret_cast<MyClass *>p; 
         ptr->doTheJob();
}

Open in new window

 

note, there are many programmers (including me) who don't use dynamic_cast, reinterpret_cast, static_cast or const_cast because they can all replaced by a so-called c cast:

   class A {};
   class B : public A { };
   
   void f(A * pa) {  B * pb = (B*)pa; pb->dosomething(); }

Open in new window

 

this works well as good as the c++ casts if you avoid casts in general and only use them when they are really needed and when you know what you are doing. as for the c++ casts the same principles are true but you have a much higher chance to using the wrong cast (which in most cases automatically was chosen with the c cast), i would bet that using c casts is the much safer and less error-prone technique. but as said, there might be a different meaning exist among experts.
   
Sara
phoffric\Commented:
reinterpret_cast was used heavily in one project for amorphous buffers that were filled in to hold various messages of different lengths. Unions in that project were not allowed. This approach allowed for messages to be stacked next to each other without any significant padding to achieve proper alignment.
ZoppoCommented:
@sara: "no, this would be a severe error" - I wouldn't say this generally; of course it's error prone since it's unsafe, but it's anyway possible to write correct working code using this by intention.

For example if you have to deal with structures from Win32 API where different variants exist, i.e. with PROCESS_MEMORY_COUNTERS (used with GetProcessMemoryInfo). For this struct an extended version PROCESS_MEMORY_COUNTERS_EX exists, the only way to distinguish between them is by comparing the first member cb with the different sizes.

So i.e. this is legitimate function:
void DoSomething( PROCESS_MEMORY_COUNTERS* pData )
{
 if ( pData->cb == sizeof( PROCESS_MEMORY_COUNTERS_EX ) )
 {
  // in C this would have been done with a old style cast: (PROCESS_MEMORY_COUNTERS_EX*)pData;
  PROCESS_MEMORY_COUNTERS_EX* pDataEx = reinterpret_cast< PROCESS_MEMORY_COUNTERS_EX* >( pData );
  ... // do something with pDataEx
 }
}

Open in new window

Please don't get me wrong, I don't want to say that this is a good technique, or encourage anyone to use it, all I want to say is that it's not necessarily a severe error.

ZOPPO
phoffric\Commented:
>> all I want to say is that it's not necessarily a severe error.
On the project I spoke of, we had independent auditors who were extremely strict in forcing us to adhere to their coding standards and style. If reinterpret_cast was universally considered in the community to be "a severe error", I strongly believe that these auditors who literally examined every line of code would have raised a major flag.
sarabandeCommented:
actually, i don't understand the discussion. in the sample code which was the base for my statement, there is a function check which takes a pointer of A while the call would like to pass a pointer of B what gives a compile error since B was not related to A. if you "repare" this by "reinterpreting" the pointer to be temporarily an A pointer (what alone is not programming but gambling), the next statement tries to cast an A pointer with a dynamic cast to a B pointer. actually, since the pointer really points to a B, i don't know what the compiler will make out of this mess, but surely a dynamic cast should return a NULL pointer if class B is not related to class A.

Sara

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
phoffric\Commented:
>> reinterpret_cast should be a rare thing in c++.
I wasn't examining your comment about the usage of reinterpret_cast for this OP, as I haven't evaluated this. I was just trying to tone down the generalization of the use of the word "rare" by showing another point of view with an extremely strict customer who audited every line of code because the code had to work perfectly. (Not 99.9% perfect, but 100% perfect.)
sarabandeCommented:
Fabrice was the first one who pointed to the fact that A and B were unrelated classes and because of that, a cast between those pointers usually is a mistake. Zoppo rightly answered that to solve the compiler errors a reinterpret_cast would help. However, with unrelated classes a reinterpret_cast only can be valid if the classes can be "equivalenced", i. e. have the same data members or share the same union structure without any class members. He also told that a reinterpret_cast wasn't always an error but could be necessary for some cases. In my last comment I made clear that in the posted original code a reinterpret_cast was wrong as the pointer later should be "cured" with a dynamic_cast back to a B pointer. Since dynamic_cast by definition is only valid between related  classes and the reinterpret_cast has "destroyed" any virtual information of the original pointer, we have at this point invalid code which probably doesn't compile but at least should fail at runtime with a null pointer.

Sara
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.