C语言中存在隐式类型转换
#include <iostream>
using namespace std;
int main(){
int n = 5;
flaot f = 10.0f;
f = n;
return 0;
}
但是这样写, 给程序员带来烦恼, 因为看到f = n
的时候, 需要判断是否发生了隐式类型转换
static_cast将这种转换明确一下, 说明隐式类型转换
...
int main(){
int n = 5;
float f = 10.0f;
f = static_cast<float>(n);
return 0;
}
什么情况下, 可以发生隐式类型转换, 什么情况下不能发生隐式类型转换
低风险的转换:
整形与浮点型, 顶多丢失了精度
double db1 = 1.0;
n = static_cast<double>(f)
字符与整形
char ch = 'a`;
n = static_cast<int>(a);
void*指针的转换
void *p = nullptr;
int *pN = static_cast<int*> (p);
转换运算符
如果类提供了转换运算符, 那么也可以通过static_cast声明 隐式类型转换
class CInt{
public:
operator int() { // 转换运算符, 可以在外界把CInt直接当成int使用
return m_nInt;
}
int m_nInt;
};
CInt nObj;
int k = static_cast<int>(nObj);
如果CInt类不提供operator int()
, 则无法通过static_cast转换, 因为不能将类(对象)转换成int
如果提供了, 就可以转换, 因为等价于CInt nObj;int kk = nObj;
static_cast声明一遍, 使得代码的可读性更好
总代码:
#include <iostream>
#include <string>
class CInt{
public:
operator int() {
return m_nInt;
}
int m_nInt;
};
int main() {
int n = 5;
double dbl = n;
char ch = 'a';
//整型与浮点型
dbl = static_cast<double>(n);
//整型与字符型
ch = static_cast<char>(n);
//转换运算符
CInt nObj;
int k = static_cast<int>(nObj);
}
高风险的转换
整形与指针类型:
编译不通过
int kk;
char* p;
// 整形与指针类型的转换
p = kk;
+static_cast<char*> 也不行
编译不通过
int kk;
char* p;
// 整形与指针类型的转换
//p = kk;
char* k = static_cast<char*>(kk);
以下也不行, 因为不加static_cast的情况下, 本来就不能通过隐式类型转换
int *pK
char* K = static_cast<char*>(pK);
基类与派生类之间的转换
父类转子类(不安全)
因为子类包含的内容更多, 父类可能访问到超越父类成员的内容, 会越界
子类转父类(安全)
子类往往内容比较多, 子类包含父类
#include "stdafx.h"
#include <iostream>
#include <string>
class CFather
{
public:
CFather() {
m_nTest = 3;
}
virtual void foo() {
std::cout << "CFather()::void foo()" << std::endl;
}
int m_nTest;
};
class CSon : public CFather
{
virtual void foo() {
std::cout << "CSon::void foo()" << std::endl;
}
};
int main() {
CFather* pFather = nullptr;
CSon* pSon = nullptr;
// 父类转子类(不安全)
//pSon = pFather;
pSon = static_cast<CSon*>(pFather); // 不安全, 没有提供运行时的检测, 也是允许的
//子类转父类(安全)
//pFather = pSon;
//pFather = static_cast<CFather*>(pSon);
}