区别于隐式的类型转换如:
//数组转指针类型
int ia[10];
int* ip = ia;
//指针转bool类型
char *cp = get_string();
if(cp)
//类类型定义的转换
string s, t="a value";
有时我们需要显示地将对象强制转换成另外一种类型.这种方法称作强制类型转换(cast),形式如下:
cast-name(expression);
任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast
题外话:
那么什么是底层const呢?
底层const表示指针所指对象或是引用对象是一个常量,举一个栗子:int i = 0; int *const p1 = &i; //顶层const const int ci = 25; //顶层const,不能改变ci的值 const int* p2 = &ci; //底层const,指针p2的值是可以改变的,ci的值是不可改变的 const int* const p3 = p2; //右边的const是顶层const,左边的const是底层的底层const const int &m = ci; //引用的const都是底层const
换句话说,只要expression指向的内存是能被修改的,就可以使用static_cast
用法:
(1)用于基本数据类型之间的转换,如把int转换为char,把int转换成enum,但这种转换的安全性需要开发者自己保证(这可以理解为保证数据的精度,即程序员能不能保证自己想要的程序安全),如在把int转换为char时,如果char没有足够的比特位来存放int的值(int>127或int<-127时),那么static_cast所做的只是简单的截断,及简单地把int的低8位复制到char的8位中,并直接抛弃高位。
(2)把void*(这个不叫空指针)转换成目标类型指针,如:
void* p4 = &i;
int* ip = static_cast<int*>(p4);
(3)把任何类型的表达式类型转换成void类型
(4)用于类层次结构中父类和子类之间指针或引用的转换。
对于以上第(4)点,存在两种形式的转换,即上行转换(子类到父类)和下行转换(父类到子类)。对于static_cast,上行转换时安全的,而下行转换时不安全的,为什么呢?因为static_cast的转换时粗暴的,它仅根据类型转换语句中提供的信息(尖括号中的类型)来进行转换,这种转换方式对于上行转换,由于子类总是包含父类的所有数据成员和函数成员,因此从子类转换到父类的指针对象可以没有任何顾虑的访问其(指父类)的成员。而对于下行转换为什么不安全,具体原理在dynamic_cast中说明。
static_cast具有编译期类型检查
dynamic_cast具有运行时类型检查,因此可以保证下行转换的安全性,何为安全性?即转换成功就返回转换后的正确类型指针,如果转换失败,则返回0(如果是引用就抛出bad_cast异常),之所以说static_cast在下行转换时不安全,是因为即使转换失败,它也不返回。
dynamic_cast适用于以下情况:
1.上行转换(安全)
2.下行转换:当我们想使用基类对象的指针或引用执行某个派生类操作并且该操作不是虚函数.一般来说我们可以使用虚函数完成运行时多态.但是当我们没有使用虚函数的时候,我们则可以使用dynamic_cast完成这一操作,但是这种操作是存在着潜在的风险的,所以程序员必须知道dynamic_cast进行强转会不会成功.(最好使用虚函数)
dynamic_cast用法与static_cast不一样
指针类型转换:
Base* p = new Child();
if(Child* pb = static_cast<Child*>(p))
{
} else {
cout << "error" <<endl;
}
引用类型转换:
void f(const Base& b)
{
try{
const Child &d = dynamic_cast<const Child&>(b);
} catch (bad_cast) {
//TODO
}
}
!!!dynamic_cast会比较虚函数表,也就是一层一层匹配v-table,开销巨大
故,如果继承深度不深的话,可以考虑
如果是多继承,建议使用
const_cast只能改变运算对象的底层const
换言之,const_cast可以将一个只读对象变成“可读写”对象,但是如果对象是常量就会产生未定义的结果
使用方式:
const char* pc; char* p = const_cast<char*>(pc); const int i = 1; int s = const_cast<int>(i); //这是错误的
举个栗子:
int *ip;
char* pc = reinterpret_cast<char*>(ip);
char* ps = static_cast<char*>(ip); //错误
type(expr);
(type) expr;
举个栗子:
int a = 2;
char c = (char)a;
参考文章:
https://blog.csdn.net/qq_26849233/article/details/62218385
https://blog.csdn.net/debugconsole/article/details/9379627 (不是原文)