C++类型安全

http://blog.csdn.net/btwsmile/article/details/6693178

什么是类型安全?

类型安全很大程度上可以等价于内存安全,类型安全的代码不会试图访问自己没被授权的内存区域。“类型安全”常被用来形容编程语言,其根据在于该门编程语言是否提供保障类型安全的机制;有的时候也用“类型安全”形容某个程序,判别的标准在于该程序是否隐含类型错误。类型安全的编程语言与类型安全的程序之间,没有必然联系。好的程序员可以使用类型不那么安全的语言写出类型相当安全的程序,相反的,差一点儿的程序员可能使用类型相当安全的语言写出类型不太安全的程序。绝对类型安全的编程语言暂时还没有。

C语言的类型安全

C只在局部上下文中表现出类型安全,比如试图从一种结构体的指针转换成另一种结构体的指针时,编译器将会报告错误,除非使用显式类型转换。然而,C中相当多的操作是不安全的。以下是两个十分常见的例子:

(1)printf格式输出

/* - print.cpp * version:1.1 */
int main()
{  printf("%d\n",10);  system("pause");  return 0;
}  

上面的代码很简单,printf函数中,%d与10匹配,结果正确。

稍作修改:

/* - print.cpp * version:1.2 */
int main()
{  printf("%f\n",10);  system("pause");  return 0;
}  

%f浮点数与10并不匹配,但是编译通过,执行也没报错,但是结果却是:

0.000000
请按任意键继续. . .
更进一步,把%f修改为%s,编译通过,执行将报错Access Violation。

(2)malloc函数的返回值

malloc是C中进行内存分配的函数,它的返回类型是void*即空类型指针,常常有这样的用法char* pStr=(char*)malloc(100*sizeof(char)),这里明显做了显式的类型转换。类型匹配尚且没有问题,但是一旦出现int* pInt=(int*)malloc(100*sizeof(char))就很可能带来一些问题,而这样的转换C并不会提示错误。

C++的类型安全

如果C++使用得当,它将远比C更有类型安全性。相比于C,C++提供了一些新的机制保障类型安全:

(1)操作符new返回的指针类型严格与对象匹配,而不是void*;

(2)C中很多以void*为参数的函数可以改写为C++模板函数,而模板是支持类型检查的;

(3)引入const关键字代替#define constants,它是有类型、有作用域的,而#define constants只是简单的文本替换;

(4)一些#define宏可被改写为inline函数,结合函数的重载,可在类型安全的前提下支持多种类型,当然改写为模板也能保证类型安全;

(5)C++提供了dynamic_cast关键字,使得转换过程更加安全,因为dynamic_cast比static_cast涉及更多具体的类型检查。

即便如此,C++也不是绝对类型安全的编程语言。如果使用不得当,同样无法保证类型安全。比如下面两个例子:

int i=5;
void* pInt=&i;
double d=(*(double*)pInt);
cout<<d<<endl;  

输入结果不是5,而意想不到的结果:-9.25596e+061。又比如:

#include<iostream>
using namespace std;  class Parent
{
};
class Child1:public Parent
{
public:  int i;  Child1(int e):i(e)  {  }
};
class Child2:public Parent
{
public:  double d;  Child2(double e):d(e)  {  }
};
int main()
{  Child1 c1(5);  Child2 c2(4.1);  Parent* pp;  Child1* pc1;  pp=&c1;  pc1=(Child1*)pp;  //#1 强制转换,由于类型仍然为Child1*,不造成错误  cout<<pc1->i<<endl;  pp=&c2;  pc1=(Child1*)pp;  //#2 强制转换,且类型发生变化,将造成错误  cout<<pc1->i<<endl;  system("pause");  return 0;
} 

结果如下:

5
1717986918
请按任意键继续. . .

上面两个例子之所以引起类型不安全的问题,是因为程序员使用不得当。第一个例子用到了空类型指针void*,第二个例子则是在两个类型指针之间进行强制转换。因此,想保证程序的类型安全性,应尽量避免使用空类型指针void*,尽量不对两种类型指针做强制转换。

C++是类型安全的吗?相关推荐

  1. 函数式思维: 利用 Either 和 Option 进行函数式错误处理 类型安全的函数式异常...

    当您研究函数式编程等深奥学科时,令人着迷的分支偶尔会出现.在 函数式思维:函数设计模式,第 3 部分 中,我在迷你系列中继续以函数的方式重新思考传统的 Gang of Four 设计模式.在下一期文章 ...

  2. Data Geekery发布了Java ORM工具jOOQ的3.9.0版,用于构建类型安全查询

    Data Geekery公司发布了其Java对象关系映射(ORM,Object-Relational Mapping)工具包jOOQ的3.9.0版.jOOQ首次推出于2010年8月,实现从数据库生成代 ...

  3. php设计模式中的类型安全 指--只接受特定的对象 ---以避免发生错误

    在百度百科中---类型安全代码指访问被授权可以访问的内存位置 转载于:https://www.cnblogs.com/zuoxiaobing/p/3581743.html

  4. SpringBoot中使用类型安全的配置来注入大量自定义属性

    场景 使用@Value注入每个自定义属性很麻烦,当自定义属性很多时就需要注入很多次. SpringBoot提供了基于类型安全的配置方式,通过@ConfigurationProperties将prope ...

  5. Java是类型安全的语言,而C++是非类型安全的?【解释】

    有过C++开发经验的人会发现,我们可以将0作为false,非零作为true.一个函数即使是bool类型的,但是我们还是可以返回int类型的,并且自动将0转换成false,非零转换成true.代码实例如 ...

  6. boost::type_erasure模块实现类型安全的 printf的测试程序

    boost::type_erasure模块实现类型安全的 printf的测试程序 实现功能 C++实现代码 实现功能 boost::type_erasure模块实现类型安全的 printf的测试程序 ...

  7. C++是不是类型安全的?

    不是.因为两个不同类型的指针之间可以强制转换(用reinterpret cast).C#是类型安全的.

  8. 编译期间确定类型安全——泛型(Generics)

    泛型是提供给Javac编译器使用的.可以限定集合中输入的类型,让编译器挡住原始程序的非法输入,编译器编译带类型说明的集合时会去掉"类型"信息,使程序运行效率不受影响,对于参数化的泛 ...

  9. JSON 序列化与反序列化:使用TypeReference 构建类型安全的异构容器

    1. 泛型通常用于集合,如Set和Map等.这样的用法也就限制了每个容器只能有固定数目的类型参数,一般来说,这也确实是我们想要的. 然而有的时候我们需要更多的灵活性,如数据库可以用任意多的Column ...

最新文章

  1. C++用substr()函数消除前后空格
  2. 【Vegas原创】X connection to localhost:11.0 broken (explicit kill or server shutdown)解决方法...
  3. sql exist 优化查询时间
  4. css transtion不生效_CSS中transition属性不起作用的原因及解决方法
  5. linux 远程桌面配置,linux 远程桌面的配置
  6. 使用CName记录的好处(转)
  7. 不会写漂亮代码不是优秀的程序员,没有钢铁侠之躯不是合格的程序员
  8. java线程知识点拾遗(1)
  9. 全卷积网络 FCN 详解(很好,详看)
  10. 修改Ubuntu的键盘映射
  11. 4 实验项目_Android开发环境搭建
  12. android拦截彩信,Android手机恶意彩信拦截系统的设计和实现
  13. 2022年最好的游戏引擎是什么?
  14. JavaScript中的alert
  15. 技术展示:综合布线系统的设计分析
  16. python游戏编程培训
  17. DirectShow 下载
  18. 通俗易懂的斯特林数介绍
  19. 高中计算机专业教师 教学计划,信息技术教师教学计划
  20. 鸿蒙遗石是什么意思,《走近》:一方歙砚,这是徽州千年遗石,也是一生匠心...

热门文章

  1. 【Android 应用开发】Ubuntu 下 Android Studio 开发工具使用详解 (旧版本 | 仅作参考)
  2. vue3.0以上关于打包后出现空白页和路由不起作用
  3. Yuan先生的博客网址
  4. 安装Adventure Works 2008 R2演示数据库
  5. JavaScript URL编码 代码片段记忆
  6. 超经典的存储过程分页 ;-) 引自CSDN网友所作
  7. LeetCode算法题3:求最大子序列和
  8. 图数据库Neo4j全栈Web技术解密
  9. 【心灵鸡汤】高情商者的15个表现
  10. miller_rabin_素性测试