Click here to Skip to main content
15,884,388 members
Please Sign up or sign in to vote.
4.20/5 (2 votes)
See more:
I was trying to understand static_cast and testing with the following code:

C++
#include <iostream>

using namespace std;

class Base
{
public:
  virtual void Func()
  {
     cout<<"Base Func()"<<endl;
  }
};
 
class Derived : public Base
{
public:
  void Func()
  {
     cout<<"Derived Func()"<<endl;
  }
 
  void Func1()
  {
     cout<<"Derived Func1()"<<endl;
  }
};
 

int main(int argc, _TCHAR* argv[])
{
	Base* pB1 = new Base();
	Base* pB2 = new Derived();
	Derived* pD1;
 
	pD1 = static_cast<Derived*>(pB1);
	pD1->Func1();            //Should get run time error as the actual object is
							//of type Base and Base does not contain Func1();

	pD1 = static_cast<Derived*>(pB2);  //It is OK as expected
	pD1->Func1();
}</blockquote>


It should generate a run time error while calling first pD1->Func1(). But it is running successfully and the out put is:

Derived Fuc1()
Derived Fuc1()

Can anyone explain why I didn't get a run time error. Also please demonstrate when run time errors are generated with using static_cast.
Posted
Updated 19-May-15 21:45pm
v3

Well I can see why you would want it to fail, and Func1 doesn't exist on Base how can it be Ok to call that method?

The thing is when you do the down-cast using static_cast you're essentially telling the compiler "just trust me on this, I know what I am doing" and since the Func1 method in you example doesn't touch any data related to the instance it's going to "work" even though it really shouldn't (this is because instance functions are pretty much just static functions where the compiler pass the instance as a secret first parameter called this).

To check this you can add an int member initialized to 0 to Derived and print it's value in Func1, when Func1 is called for a Derived it will have a the value of the memory where the int would have been had it been a Derived instance.

What you want to do is not use static_cast and use dynamic_cast with Runtime Type Information enabled, that might cause it to fail earlier.

Remember that C++ will let you do whatever you want, so you need to be careful, for example, you could add the following to your code;
C++
string s = *reinterpret_cast<string*>(pB1);

And it would compile and run. Behaviour of that string will be undefined though.
 
Share this answer
 
Comments
Leo Chapiro 20-May-15 3:47am    
+5 Perfect explained!
Shubha Debnath 20-May-15 6:00am    
Hi Fredrik, Thanks for your explanation. Its pretty cool.
As per your suggestion I have used a member variable and tried to access it from the Func1(). The behavior of this variable is undefined but it is not throwing any run time exception.
Fredrik Bornander 20-May-15 7:08am    
It would have to be a dynamic_cast for it to throw an exception.
 
Share this answer
 
Comments
Leo Chapiro 20-May-15 3:46am    
-1 because this is not an answer.
Jochen Arndt 20-May-15 3:49am    
The link contains the answer:
"In contrast to dynamic_cast, no run-time check is made on the static_cast conversion"
Leo Chapiro 20-May-15 4:02am    
In this case this answer should be included in the solution, shouldn't it?
Jochen Arndt 20-May-15 4:09am    
Yes, it would be a better answer with that cite.
I just wanted to point out that it is an answer because the link contains all necessary information.
Richard MacCutchan 20-May-15 4:10am    
The answer is in the link, if you care to go and read it.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900