the c++ casting operators

the four c++ casting operators are

  • static_cast
  • dynamic_cast
  • reinterpret_cast
  • const_cast

use static_cast

static_cast is a mechanism that can be used to convert pointers between related types, and perform explicit type conversions for standard data types that would otherwise happen automatically or implicitly.

casting a Derived* to a Base* is called upcasting while casting a Base* to a Derived* is called downcasting.

1
2
Derived ObjFoo;
Base* ObjBaseFoo = &ObjFoo;

however

1
2
3
Derived ObjFoo;
Base* ObjBaseFoo = &ObjFoo;
Derived* AnotherObjFoo = ObjBaseFoo; //error!!!!

using dynamic_cast and runtime type identification

the typical usage syntax of the dynamic_cast operator is

1
2
3
destination_type* Dest = dynamic_cast<class_type*>(Source);
if(Dest)
Dest->CallFunc();

e.g. using dynamic casting to tell whether a fish object is a tuna or a carp demolist13_1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>
using namespace std;

class Fish
{
public:
virtual void Swim()
{
cout << "fish swim in water " << endl;
}
virtual ~Fish() {}
};
class Tuna : public Fish
{
public:
void Swim()
{
cout << "tuna swim " << endl;
}

void BecomeDinner()
{
cout << "Tuna Dinner " << endl;
}
};

class Crap : public Fish
{
public:
void Swim()
{
cout << "Crap Swim " << endl;
}

void Talk()
{
cout << "crap talk " << endl;
}
};

void DetectFishType(Fish* ObjFish)
{
Tuna*ObjTuna = dynamic_cast<Tuna*>(ObjFish);
if(ObjTuna)
{
cout <<"detect tunna dinner "<<endl;
ObjTuna->BecomeDinner();
}
Crap*ObjCrap = dynamic_cast<Crap*>(ObjFish);
if(ObjCrap)
{
cout <<"detect crap talk "<<endl;
ObjCrap->Talk();
}

cout<<"type check "<<endl;
ObjFish->Swim();
}

int main()
{
Crap MyLunch;
Tuna MyDinner;

DetectFishType(&MyLunch);
cout<< endl;
DetectFishType(&MyDinner);

return 0;
}

Line 41-54 is used to test the nature of the input base class pointer of type Fish. the return value of dynamic_cast operation should always be checked for validity . It's NULL when the cast fails.

using reinterpret_cast

reinterpret_cast really does allow you to cast one object type to another, regardless of whether or not the types are related. syntax as seen in the following sample:

1
2
Base* objBase = new Base();
Unrelated* notRelated = reinterpret_cast<Unrelated*>(objBase);

using const_cast

const_cast enables you to turn off the const access modifier to an object. A prevalent error like the follow sample:

1
2
3
4
5
6
7
8
9
10
11
class Foo
{
public:
void DisplayMembers();
};

void DisplayData (const Foo& ObjFoo)
{
ObjFoo.DisplayMembers();//error!!
//call to a non-const member using a const reference
}

we can make corrective changes to DisplayMembers(). The syntax for invoking DisplayMembers() in such a scenario is

1
2
3
4
5
void DisplayData (const Foo& ObjFoo)
{
Foo& RefData= const_cast<Foo&>(ObjFoo);
RefData.DisplayMembers(); // Allowed!
}

const before or after function

来源:const在函数前后的区别

const放在函数后主要是限制类中的成员函数,const放在函数前是限制函数返回类型为指针时通过指针对返回值的修改。

  1. const在函数前: const在函数前实际上是约束函数的返回的,表明返回的值不能做左值,实际上就是防止返回值直接被赋值。但是一般的变量无法修改函数返回值,其实是为了防止函数返回类型为指针类型时,通过指针对返回值进行修改。非指针的函数返回类型前加const是没有意义的

  2. const在函数后: const放在函数后通常是用在类中,限制类的成员函数不能对成员变量进行修改。同时,被函数后的const修饰的成员函数也不能调用其 他非const的成员函数。

Q: I need a Bird*, but have a Dog* at hand. The compiler does not allow me to use the pointer to the Dog object as a Bird*. However, when I use reinterpret_cast to cast the Dog* to Bird*, the compiler does not complain and it seems I can use this pointer to call Bird’s member function, Fly(). Is this okay? A: Again, definitely not. reinterpret_cast changed only the interpretation of the pointer, and did not change the object being pointed to (that is still a Dog). Calling a Fly() function on a Dog object will not give the results you are looking for, and could possibly cause an application failure.