C++ Primer笔记2_四种类型转换_异常机制
1.类型转换
命名的强制类型转换:
有static_cast、dynamic_cast、const_cast、reinterpret_cast
static_cast:
编译器隐式运行的不论什么类型转换都能够由static_cast完毕
当一个较大的算术类型赋值给较小的类型时。能够用static_cast进行强制转换。
能够将void*指针转换为某一类型的指针
能够将基类指针强制转换为派生类指针,可是不安全。
无法将const转化为nonconst。这个仅仅有const_cast才干够办得到
举例:
double d = static_cast<double>(j) / i; void *p = &d;
double *dp = static_cast<double*>(p);
const_cast:
用来移除对象的常量性(cast away the constness), const_cast一般用于指针或者引用。
对于将常量对象转换为很常量对象的行为,一旦去掉了const性质。编译器就不再阻止我们对该对象的写操作,结果是没有定义的。
const char *pc;
char *p = const_cast<char*>(pc);//正确:可是通过p写值是没有定义的行为;
char *p = static_cast<char *>(pc);//错误。static_cast不能转换掉const性质
static_cast<string>(pc);//正确。字符串字面值转换为string
const_cast<string>(pc);//错误,const_cast仅仅改变常量属性
看以下一个样例:
#include <iostream>
using namespace std; int main(void)
{
const int a = 100;
int *pA = const_cast<int *>(&a);
*pA = 200; int &refA = const_cast<int &>(a);
refA = 300; // int *pA1 = static_cast<int *>(&a); Error cout << "*pA:" << *pA << endl;//300
cout << "refA:" << refA << endl;//300
cout << "a:" << a << endl;//100 return 0;
}
发现通过const_cast转换后,去除了const属性,然后对变量改动,执行时内存中的值是改变的,但最后打印改动后的值仍为原样。
以下是网上摘录的一段解释:
const仅仅是告诉编译器不能改动而不是真正地不可改动,假设程序猿不注意而去改动了它会报错。如今我们利用const_cast去除了常量性,然后通过指针和引用对其进行了改动,所以通过指针打印或者引用传參的时候就能看出其内存确实变化了,但为了保护val这个变量本来的const特性,所以每次我们使用val时。系统都将其替换成初始值100,确保了val还是“不可变”的
reinterpret_cast
常为运算对象的位模式提供较低层次上的又一次解释。
举例:
int *pi;
char *pc = reinterpret_cast<char *>(pi);
我们必须牢记pc所指的真实对象是一个int而非字符,假设把pc当成字符指针在执行时可能出错。
如:string str(pc);
使用reinterpret_cast时很危急的,一般避免使用。
dynamic_cast:
dynamic_cast主要用于类层次间的上行转换和下行转换,还能够用于类之间的交叉转换。
在类层次间进行上行转换时。dynamic_cast和static_cast的效果是一样的。
在进行下行转换时。dynamic_cast具有类型检查的功能,比static_cast更安全。
1.
安全的基类和子类之间转换。
2. 必需要有虚函数。
3. 同样基类不同子类之间的交叉转换。但结果是NULL。
样例:
#include <iostream>
using namespace std; class A
{
protected:
int n;
public:
A(){n = 10;}
virtual void getN(){}
}; class B : public A
{
string name;
public:
B(){name = "SCOTT";}
virtual void getN()
{
cout << "B: " << n << endl;
}
void printf()
{
cout << "name: " << name << endl;
}
}; void Test(A * pA)
{
B *pB1 = static_cast<B *>(pA);
cout << "pB1: " << pB1 << endl; B *pB2 = dynamic_cast<B *>(pA);
cout << "pB2: " << pB2 << endl;
} int main()
{
A *pA1 = new A;
A *pA2 = new B; Test(pA1);//pB2为空指针 dynamic_cast将做类型检查,pB1尽管正确,但对其操作是不安全的,从这里能够看出static_cast没有dynamic安全
Test(pA2);//OK 都是B类型对象 return 0;
}
总结:
去掉const属性用const_cast
主要的类型转换用static_cast
多态类之间的类型转换用dynamic_cast
不同类型指针类型转换用reinterpret_cast
參考:
http://blog.csdn.net/ljz888666555/article/details/4541232
http://blog.csdn.net/jnu_simba/article/details/8868530
2.异常机制
try-catch-throw的使用:
#include <iostream> using namespace std; double fun(int a, int b)
{
if(0 == b)
{
throw b;
}
return a/b;
} int main()
{
double a = 0.0; try
{
a = fun(2, 0);
}
catch(int)
{
cout << "Error: b is zero!" << endl;
}
catch(...)
{
cout << "Other error!" << endl;
}
cout << "a: " << a << endl;//still run after deal exception return 0;
}
自己定义异常类:
#include <iostream>
using namespace std; class MyException
{
public:
MyException(string name = "default name")
{
cout << "New Exception: " << name << endl;
this->name = name;
}
~MyException()
{
cout << "Delete Exception: " << this->name << endl;
}
void myThrow()
{
throw MyException("Error");
}
private:
string name;
}; int main()
{
MyException m("Test");
try
{
m.myThrow();
}
catch(...)
{
cout << "*****" << endl;
} return 0;
}
执行结果:
New Exception: Test
New Exception: Error
*****
Delete Exception: Error
Delete Exception: Test
C++ Primer笔记2_四种类型转换_异常机制的更多相关文章
- C++ 四种类型转换
在写代码中经常会有很多的隐式类型转换或显式类型转换. 对于隐式的类型转换主要是放生在赋值的时候,讲变量赋值给不同类型的变量的时候就会发生类型转换,如果是宽化转换(即从占字节少的类型向占字节多的类型转换 ...
- 从零开始学C++之从C到C++(二):引用、内联函数inline、四种类型转换运算符
一.引用 (1).引用是给一个变量起别名 定义引用的一般格式:类型 &引用名 = 变量名: 例如:int a=1; int &b=a;// b是a的别名,因此a和b是同一个单元 注 ...
- C++语言中的四种类型转换
1 引子 这篇笔记是根据StackOverflow上面的一个问题整理而成,主要内容是对C/C++当中四种类型转换操作进行举例说明.在之前其实对它们都是有所了解的,而随着自己在进行总结,并敲了一些测试示 ...
- 引用、数组引用与指针引用、内联函数inline、四种类型转换运算符
一.引用 (1).引用是给一个变量起别名 定义引用的一般格式:类型 &引用名 = 变量名: 例如:int a=1; int &b=a;// b是a的别名,因此a和b是同一个单元 ...
- [转]C++中四种类型转换符的总结
C++中四种类型转换符的总结 一.reinterpret_cast用法:reinpreter_cast<type-id> (expression) reinterpret_cast操 ...
- c++ --> c++中四种类型转换方式
c++中四种类型转换方式 c风格转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少缺点, 1)它可以在任意类型之间转换,比如你可以把一个指向const对象的指针转换成指向 ...
- 【转】C++四种类型转换方式
C++四种类型转换方式 https://blog.csdn.net/lv_amelia/article/details/79483579 C风格的强制类型转换(Type Case)很简单,不管什么类型 ...
- C++中四种类型转换以及const_cast是否能改变常量的问题
we have four specific casting operators:dynamic_cast, reinterpret_cast, static_cast and const_cast. ...
- 【C++】类型转换简述:四种类型转换方式的说明及应用
本文主要简述在C++中四种类型转换的方式:static_cast.reniterpret_cast.const_cast和dynamic_cast. 在介绍C++类型转换方式之前,我们先来看看C语言的 ...
随机推荐
- 【剑指offer】面试题 17. 打印从 1 到最大的 n 位数
面试题 17. 打印从 1 到最大的 n 位数 题目描述 题目:输入数字 n,按顺序打印出从 1 最大的 n 位十进制数.比如输入 3,则打印出 1.2.3 一直到最大的 3 位数即 999. 解答过 ...
- thinkphp图片上传+validate表单验证+图片木马检测+缩略图生成
目录 1.案例 1.1图片上传 1.2进行图片木马检测 1.3缩略图生成 1.4控制器中调用缩略图生成方法 1.案例 前言:在thinkphp框架的Thinkphp/Library/Thin ...
- 《深入浅出Nodejs》笔记——模块机制(2)
前言 书上还有很大一部分讲了C/C++模块的编译过程.核心模块编写和C/C++扩展模块的内容,不过我对C++一窍不通因此没有仔细看,如果以后需要再自习看吧. 包与NPM 第三方模块中,模块和模块之间是 ...
- RabbitMQ (十五) 镜像集群 + HAProxy1.7.8 负载均衡
RabbitMQ 默认的集群模式,也就是普通模式,最大的问题就在于存储队列完整数据的节点一旦宕机, 如果是非持久化队列,则消息丢失;如果是持久化队列+持久化消息,则必须等该节点恢复. 所以后来 Rab ...
- thinkphp结合bootstrap打造个性化分页
分页功能是web开发中常见的一项功能,也存在很多形式,这里主要讲一下利用thinkPHP框架的page类来打造一款bootstrap风格的分页过程. 首先需要去thinkPHP官网现在其分页扩展类ht ...
- nyoj 300 (矩阵快速幂)Kiki & Little Kiki 2
描述 There are n lights in a circle numbered from 1 to n. The left of light 1 is light n, and the left ...
- 【构造】Gym - 101411F - Figure ans Spots
在最外围的一圈没有意义,所以全都涂黑,内部贪心地涂成棋盘即可. #include<cstdio> #include<cstring> using namespace std; ...
- datatable无法设置横向滚动条(设置无效)
datatable设置横向滚动条无效 js如下: 页面如下: 设置 scrollx 属性为true时,还需在 table 添加 style="white-space: nowrap; &qu ...
- [转]iBatis简单入门教程
iBatis 简介: iBatis 是apache 的一个开源项目,一个O/R Mapping 解决方案,iBatis 最大的特点就是小巧,上手很快.如果不需要太多复杂的功能,iBatis 是能够满足 ...
- winform listview默认第一项光标选中
if (this.lsvSortingHeadList.Items.Count > 0) { this.lsvSortingHeadList.Focus(); this.lsvSortingHe ...