php做网站好学吗,搜索引擎的使用方法和技巧,制作网页之前必须先建立什么,h5制作网站 有哪些本专栏目的
更新C/C的基础语法#xff0c;包括C的一些新特性
前言
通过前面几节课#xff0c;我们学习了抽象、封装、继承、多态、异常等概念#xff0c;这一篇我们将继续学习C的类型转换#xff0c;和C语言还有很大区别的#xff1b;在本节课最后#xff0c;也简要说…本专栏目的
更新C/C的基础语法包括C的一些新特性
前言
通过前面几节课我们学习了抽象、封装、继承、多态、异常等概念这一篇我们将继续学习C的类型转换和C语言还有很大区别的在本节课最后也简要说了一下在计算机视角上看类型是什么样子的C语言后面也会继续更新知识点如内联汇编欢迎收藏 关注本人将会持续更新。 文章目录 类型转换问题抛出(C语言的缺陷)static_castreinterpret_castconst_castdynamic_cast小结与类型转换本质简说 类型转换
问题抛出(C语言的缺陷) 首先先回忆一下C中的类型转换再C语言中类型转换很简单只需要再需要修改类型的地方前添加(datatype)datatype为要转换的类型 但是这样其实是很不严谨的我们来看一下这样一个案例(C语言中)
#include stdio.hint main()
{const int a 10;const int* p a;int* pp (int*)p;*pp 20;printf(%d %d %d\n, a, *p, *pp);
}输出
20 20 20这个时候我们来分析一下变量a是一个const修饰的变量我们也声明了一个指针常量p指向变量a的地址这个时候我们通过强制转换强制转换成int*类型将指针p转换成普通指针pp这个时候通过指针pp修改变量a的值然后输出通过输出发现将常量a修改成功了这显然不符合常理♂♂♂注意这个时候如果用CPP文件去运训会得到以下结果
10 20 20这是因为C他做了优化会将a变量再只读区域储存一份这个可以参考之前的博客 C/C的不同
所以C为了规范C中的类型转换加强类型转换的可视性引入了四种强制类型转换操作符
static_castreinterpret_castconst_castdynamic_cast
下面我们分别来学习这几个类型转换。
static_cast static_cast(expression)该运算符把expression转换为type-id类型 static_cast关键字是再编译阶段完成的不提供动态类型检查所以再我们写的时候就需要经量保证这个类型之间是可以转换的防止出现上行转换这样的当然现在很多编译器都有自己的检查机制会自动帮我们检查如vs但是linux上编程是不会的。 应用编译器隐式执行任何类型转换都可由static_cast显示完成编译器隐式编译器再编译的时候自动帮我们操作所以我们需要保证再写的时候需要保证可以转换这个就得看经验积累了常用如下 ⚾️ 基本类型转换 double score 59.5;
int nScore static_castint(score);⚡️ void指针和其他类型指针之间的转换 void* p new int(20);
int* pi static_castint*(p);
void* pc static_castvoid*(pi); //这里可以隐式转换可以省略static_cast
delete p;️ 用于基类派生类之间指针、引用的转换 class Base
{
public:virtual void show(){std::cout Base std::endl;}
};class Derive :public Base
{char* name nullptr;
public:Derive(){name new char[5]{ 玩蛇 };}~Derive(){delete name;}void print(){std::cout Derive name std::endl;}
};**上行转换**把派生类指针、引用转为基类的指针、引用可以自动隐式转换 //指针
Derive* derive new Derive;
Base* base static_castDerive*(derive); // 转换成基类
//引用
Derive refDerive *derive;
Base refBase static_castBase(refDerive); // 转换成基类delete derive;⏬ **下行转换**把基类指针、引用转为派生类的指针、引用必须强制静态转换 Base* base new Base;
Derive* derive static_castDerive*(base);
derive-print();delete base;⚠️ **注意**下行转换使用static_cast 不安全请使用dynamic_cast不安全因为不知道基类的指针到底是不是指向的要转换的派生类对象如果不是访问数据成员会有错误
reinterpret_cast
这个可以用于任意指针之间的转换不安全不推荐使用了解即可。
主要用于以下六种情况 任意类型指针之间的转换 int* p nullptr;
char* pc reinterpret_castchar*(p);指针转整型整型转指针 int* p nullptr;
uint64_t a reinterpret_castuint64_t(p); //x64 指针是8个字节所以要用uint64_t保存否则可能会丢失数据
double* pd reinterpret_castdouble*(a);函数指针也可以转换 uint64_t funMax reinterpret_castuint64_t(_max);
coutreinterpret_castint(*)(int, int)(funMax)(2, 3);int _max(int a, int b)
{return a b ? a : b;
}一个官方案例 int arr[10];
for (int i 0; i 10; i)
{cout arri hex ::hash(arri) endl;;
}uint32_t _hash(void* p)
{uint64_t val reinterpret_castuint64_t(p);return val ^ (val 32);
}const_cast
const_cast用来移除类型的const属性所以const_cast 中的类型必须是指针、引用或指向对象类型成员的指针引用的本质也是常量指针). const指针、引用不能直接赋值给非const的对象需要去掉const之后再赋值 const char* name hello;
char* pname const_castchar*(name); // 转化成非const类型const int refA 8;
int refB const_castint(refA);可以在类的const函数里面修改成员变量 class Integer
{
private:int number;
public:Integer(int number 0):number(number){}operator int()const // const说明里面的不允许有变量发送改变{const_castint(number); //必须去掉const才能修改const_castInteger*(this)-number;return number;}
};Integer num 10;
int n num; //11dynamic_cast
dynamic_cast用于有继承关系的多态类基类必须有虚函数的指针或引用之间的转换即父子类之间的转换且安全。
通过dynamic_cast将派生类指针转换为基类指针上行转换这个操作与static_cast的效果是一样的。通过dynamic_cast将基类指针转换为派生类指针下行转换dynamic_cast具有类型检查的功能比static_cast更安全如果转换的是指针失败时会返回空指针如果转换的是引用会抛出std::bad_cast异常 使用场景 指针转换转换失败返回nullptr更安全 Animal* dog new Dog;
dog-cry();
//转成实际的类型
Dog* d dynamic_castDog*(dog);
if (!d)std::cout dog is not Dog std::endl;
d-cry();
//尝试转成其他子类,失败返回nullptr
Cat* cat dynamic_castCat*(dog); // 子转化成父
if (!cat)std::cout dog is not Cat;
elsecat-cry(); 转换引用转换失败抛异常std::bad_cast更安全 Animal refA *dog;
//转成实际的类型
Dog refD dynamic_castDog(refA); // 父转化成子
refD.cry();
//尝试转成其他子类,失败抛异常
Cat refC dynamic_castCat(refA);
refC.cry();小结与类型转换本质简说
static_cast最常用用于普通类型转换reinterpret_cast任意指针之间转换不推荐使用const_cast用去去掉const属性dynamic_cast主要用于基类与派生类之间的转换 其实再计算机内部他是没有类型这一概念的汇编也没有类型这一概念类型是高级语言自己抽象出来的类型转换就是告诉编译器这个变量属于什么类型这样再转化成汇编的时候就可以调用不同类型的汇编指令了当然还有很多要注意的比如说无符号与有符号之间的转换-1类型转换如果从位的角度来看转化成1就不单单只是加个负号这么简单了这个本人会更新后面会更新《深入理解计算机系统》这本书学习笔记到时候会有详细的讲解。