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

C语言的类型安全

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

(1)printf格式输出

  1. /* - print.cpp
  2. * version:1.1
  3. */
  4. int main()
  5. {
  6. printf("%d\n",10);
  7. system("pause");
  8. return 0;
  9. }

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

稍作修改:

  1. /* - print.cpp
  2. * version:1.2
  3. */
  4. int main()
  5. {
  6. printf("%f\n",10);
  7. system("pause");
  8. return 0;
  9. }

%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++也不是绝对类型安全的编程语言。如果使用不得当,同样无法保证类型安全。比如下面两个例子:

  1. int i=5;
  2. void* pInt=&i;
  3. double d=(*(double*)pInt);
  4. cout<<d<<endl;

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

  1. #include<iostream>
  2. using namespace std;
  3. class Parent
  4. {
  5. };
  6. class Child1:public Parent
  7. {
  8. public:
  9. int i;
  10. Child1(int e):i(e)
  11. {
  12. }
  13. };
  14. class Child2:public Parent
  15. {
  16. public:
  17. double d;
  18. Child2(double e):d(e)
  19. {
  20. }
  21. };
  22. int main()
  23. {
  24. Child1 c1(5);
  25. Child2 c2(4.1);
  26. Parent* pp;
  27. Child1* pc1;
  28. pp=&c1;
  29. pc1=(Child1*)pp;  //#1 强制转换,由于类型仍然为Child1*,不造成错误
  30. cout<<pc1->i<<endl;
  31. pp=&c2;
  32. pc1=(Child1*)pp;  //#2 强制转换,且类型发生变化,将造成错误
  33. cout<<pc1->i<<endl;
  34. system("pause");
  35. return 0;
  36. }

结果如下:

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

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

c++ 类型安全的更多相关文章

  1. 04_Swift2基础之类型安全和类型推测+字面量+类型别名

    1. 类型安全和类型推测 1> 类型安全 Swift 是一个 _类型安全(type safe)_ 的语言.类型安全的语言可以让你清楚地知道代码要处理的值的类型.如果你的代码需要一个`String ...

  2. 类型安全且自动管理内存的返回 std::string 的 sprintf 实现

    在这篇博文里,我提到了一个例子,说的是使用C++实现类型安全的printf.这个例子很惊艳,但是在我写程序的时候,并非那么"迫切"地需要它出现在我的工具箱中,因为它并不比普通的pr ...

  3. Qt信号槽机制的实现(面试的感悟,猜测每一个类保存的一个信号和槽的二维表,实际使用函数指针 元对象 还有类型安全的检查设定等等)

    因为面试时问了我这道题,导致我想去了解信号槽到底是如何实现的,于是贴着顺序看了下源码,大致了解了整个框架.网上关于信号槽的文章也很多,但是大部分都是将如何应用的,这里我就写一下我所理解的如何实现吧, ...

  4. Swift编程语言学习1.3——类型安全和投机型

    Swift 是类型安全(type safe )语言.类型安全的语言可以让你清楚地知道代码被处理值类型.假设你需要一个代码String.你绝对不能进去一个不小心传球Int. 因为 Swift 它是类型安 ...

  5. Matlab与.NET基于类型安全的接口混合编程入门

    原文:[原创]Matlab与.NET基于类型安全的接口混合编程入门 如果这些文章对你有用,有帮助,期待更多开源组件介绍,请不要吝啬手中的鼠标. [原创分享]Matlab.NET混编调用Figure窗体 ...

  6. Swift语言指南(四)--类型安全和类型推断

    原文:Swift语言指南(四)--类型安全和类型推断 Swift是一门类型安全语言,类型安全语言需要代码里值的类型非常明确.如果你的代码中有部分值需要String类型,你就不能错误地传递Int. 鉴于 ...

  7. 自动类型安全的.NET标准REST库refit

    在SCOTT HANSELMAN 博客上看到一个好东西<Exploring refit, an automatic type-safe REST library for .NET Standar ...

  8. Effective Java 第三版——33. 优先考虑类型安全的异构容器

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  9. Springboot的常规属性配置和类型安全配置

    1.类型常规配置: 通过在properties文件中注入键值对的方式,在java代码中通过@Value注解注入值 2.类型安全配置 将要注入的属性包装成一个类,给类加上注解:ConfigrationP ...

随机推荐

  1. 24Mybatis_延迟加载——用association来实现

    resultMap可以实现高级映射(使用association.collection实现一对一及一对多映射),association.collection具备延迟加载功能. 需求: 如果查询订单并且关 ...

  2. [4]Telerik Grid 简单使用方法

    1.columns <% Html.Telerik().Grid(Model) .Name("Orders") .Columns(columns => { //绑定列名 ...

  3. yslow性能优化的35条黄金守则

    参考Best Practices for Speeding Up Your Web Site Exceptional Performance 团队总结了一系列优化网站性能的方法,分成了7个大类35条, ...

  4. 【转】【Asp.Net】asp.net服务器控件创建

    VS新建一个Web服务控件工程,会默认生成以下代码: namespace WebControlLibrary { [DefaultProperty("Text")] [Toolbo ...

  5. 给vps设置ssh供爬墙使用

    在服务器上建一个 username : 添加用户:useradd -s /bin/false username,将用户的shell设置成/bin/false.这样用户就无法与系统进行交互. 设置密码: ...

  6. 【快报】基于K2 BPM的新一代协同办公门户实践交流会

    2014年2月28日,“基于BPM的新一代协同办公门户”用户实践交流活动在深圳金茂JW万豪酒店3楼Meet Room IV举办.本次会议由K2携手微软共同举办,邀请到的参会企业都是K2 的BPM老客户 ...

  7. .htaccess设置静态资源缓存(即浏览器缓存)

    在HTTP标头中为静态资源设置过期日期或最长存在时间,可指示浏览器从本地磁盘中加载以前下载的资源,而不是通过网络加载.这样, 网站加载速度会更快. 下面的代码都需要放到.htaccess中才能生效. ...

  8. pandas 给数据打标签

    import numpy as np import pandas as pd df = pd.DataFrame(np.random.randint(0,100,100), columns=['sco ...

  9. Bootstrap系列 -- 15. 下拉选择框select

    Bootstrap框架中的下拉选择框使用和原始的一致,多行选择设置multiple属性的值为multiple.Bootstrap框架会为这些元素提供统一的样式风格 <form role=&quo ...

  10. TO~亲爱的自己

    你累的时候,谢绝别人的肩膀: 你扛不动的时候,拒绝别人的帮忙: 你和别人吃饭,不让别人买单你总是想我这样优秀善良, 总不给别人添麻烦,为什么总是找不到爱的人呢? 有时,爱只有在相处时才能找得到的, 是 ...