C风格的强制类型转换,格式如下两种:
*①Class(expression);
②(Class)expression;*
第一:不安全,没有类型检查;
第二:可读性差,在代码中不容易发现做了类型转换。
C++的四类转换:reinterpret_cast,const_cast,static_cast,dynamic_cast。分别对应于不同的应用场景。
static_cast
void testStatic_Cast()
{
// 基本类型的转换
cout << "Begin of basic Type Cast--------------" << endl;
char p = 'a';
cout << "p::" << p << endl;
int i = static_cast<int>(p);
cout << "i::" << i << endl;
char q = static_cast<char>(i);
cout << "q::" << q << endl;
cout << "End of basic Type Cast--------------" << endl;
// void*与别的指针类型之间的转换
cout << "Begin of void* Type Cast--------------" << endl;
int ii = 2;
void* pvii = ⅈ
int* pii = static_cast<int*>(pvii);
cout << ii << endl;
cout << *pii << endl;
cout << "End of void* Type Cast--------------" << endl;
// 向上类型转换(安全)
cout << "Begin of Inherit Type Castcout--------------upcast" << endl;
Child child2;
Parent* parent2 = static_cast<Parent*>(&child2);
parent2->sayHello();
parent2->setChildNum(2);
cout << "Get Parent member::" << parent2->getChildNum() << endl;
cout << "End of Inherit Type Castcout--------------upcast" << endl;
// 向下类型转换(不安全)
cout << "Begin of Inherit Type Castcout--------------downcast" << endl;
Parent parent1;
Child* child1 = static_cast<Child*>(&parent1);
/*child1->sayHello();
child1->sayDad();
child1->setChildNum(2);
child1->setBrotherNum(3);*/
cout << "Get Parent member::" << child1->getChildNum() << endl;
cout << "Get Child member::" << child1->getBrotherNum() << endl;
cout << "End of Inherit Type Castcout--------------downcast" << endl;
}
对于static_cast来讲,对象指针的转换,向上转换是安全的,向下转换则不安全。
运行上面的代码,向下转换的时候代码可以执行,但执行完以后会报错如下:
const_cast
#pragma once
class ConstCastDemo
{
public:
ConstCastDemo(void);
~ConstCastDemo(void);
void setNum(int num);
int getNum() const;
private:
int m_nNum;
};
#include "StdAfx.h"
#include "ConstCastDemo.h"
ConstCastDemo::ConstCastDemo(void)
: m_nNum(0)
{
}
ConstCastDemo::~ConstCastDemo(void)
{
}
void ConstCastDemo::setNum(int num)
{
m_nNum = num;
}
int ConstCastDemo::getNum() const
{
return m_nNum;
}
void testConst_Cast()
{
const ConstCastDemo demo;
cout << "Num from demo::" << demo.getNum() << endl;
// 由于为const对象,所以不可执行非const成员方法
// demo.setNum(100);
// 不可以直接进行对象的转换(转换后会成为另一个对象?)
/*ConstCastDemo demo1 = const_cast<ConstCastDemo>(demo);
demo1.setNum(100);
cout << "Num from demo::" << demo.getNum() <<endl;
cout << "Num from demo1::" << demo1.getNum() <<endl;*/
// 进行指针的转换,脱去const
ConstCastDemo* demo2 = const_cast<ConstCastDemo*>(&demo);
demo2->setNum(200);
cout << "Num from demo::" << demo.getNum() << endl;
cout << "Num from demo2::" << demo2->getNum() << endl;
// 进行引用的转换,脱去const
ConstCastDemo& demo3 = const_cast<ConstCastDemo&>(demo);
demo3.setNum(300);
cout << "Num from demo::" << demo.getNum() << endl;
cout << "Num from demo3::" << demo3.getNum() << endl;
}
dynamic_cast
#pragma once
class Parent
{
public:
Parent(void);
virtual ~Parent(void);
void sayHello();
void setChildNum(int num);
int getChildNum();
private:
int m_nChildNum;
};
#include "StdAfx.h"
#include "Parent.h"
#include <iostream>
using namespace std;
Parent::Parent(void)
{
}
Parent::~Parent(void)
{
}
void Parent::sayHello()
{
cout << "Parent::say::" << "hello, boy!" << endl;
}
void Parent::setChildNum(int num)
{
m_nChildNum = num;
}
int Parent::getChildNum()
{
return m_nChildNum;
}
#include "Parent.h"
#pragma once
class Child : public Parent
{
public:
Child(void);
virtual ~Child(void);
void sayDad();
void setBrotherNum(int num);
int getBrotherNum();
private:
int m_nBrotherNum;
};
#include <iostream>
using namespace std;
Child::Child(void)
: Parent()
{
}
Child::~Child(void)
{
}
void Child::sayDad()
{
cout << "Child::say::" << "Hello, dad!" << endl;
}
void Child::setBrotherNum(int num)
{
m_nBrotherNum = num;
}
int Child::getBrotherNum()
{
return m_nBrotherNum;
}
void testDynamic_Cast()
{
/*
①dynamic_cast作用于类指针或者类引用;
②dynamic_cast用于向上转换或者向下转换;
③指针转换的时候,如果失败,返回NULL指针;
④引用转换的时候,如果失败,则跑出bad_cast异常;
*/
cout << "Begin to test dynamic_cast--------------Parent to Child" << endl;
Parent* parent1 = new Parent();
Child* child1 = dynamic_cast<Child*>(parent1);
if (child1 == NULL)
{
cout << "pointer dynamic_cast downcast failed!" << endl;
}
else
{
cout << "pointer dynamic_cast downcast succeed!" << endl;
}
/*Child& child2 = dynamic_cast<Child&>(*parent1);*/
Parent& parent2 = *parent1;
try
{
Child& child2 = dynamic_cast<Child&>(parent2);
cout << "reference dynamic_cast downcast succeed!" << endl;
}
catch (...)
{
cout << "reference dynamic_cast throw exception!" << endl;
}
cout << "End of test dynamic_cast--------------Parent to Child" << endl;
cout << "Begin to test dynamic_cast--------------Child to Parent" << endl;
Child* child3 = new Child();
Parent* parent3 = dynamic_cast<Parent*>(child3);
if (parent3 == NULL)
{
cout << "pointer dynamic_cast upcast failed!" << endl;
}
else
{
cout << "pointer dynamic_cast upcast succeed!" << endl;
}
Child& child4 = *child3;
try
{
Parent& parent4 = dynamic_cast<Parent&>(child4);
cout << "reference dynamic_cast upcast succeed!" << endl;
}
catch (...)
{
cout << "reference dynamic_cast throw exception!" << endl;
}
cout << "End of test dynamic_cast--------------Child to Parent" << endl;
}
reinpreter_cast
谨慎使用reinpreter_cast!!!!