C++11:提高类型安全
来源:互联网 发布:wifi模块与单片机通信 编辑:程序博客网 时间:2024/06/14 08:09
1 强类型枚举
C98的enum是非强类型作用域(在一个子命名空间定义的enum其父空间也可加enum成员,即enum相当于全局的,容易引起重复值),允许隐式类型转换(这条规则可以允许不同enum类型间相互比较成员值),占用存储空间及符号性不确定。C++11引入了强类型枚举enum class/struct具有以下特点:强作用域,子空间的枚举成员不会输出到父空间中; 转换限制,枚举成员的值不可以与整型隐式的相互转换,static_cast这样的强制转换还是可以的; 可以指定底层类型,即枚举成员的的底层存储类型可以自行指定,如char或unsigned int。使用如下:
#include <iostream>using namespace std;enum class Type { General, Light, Medium, Heavy };enum class Category { General = 1, Pistol, MachineGun, Cannon };int main() { Type t = Type::Light; t = General; // 编译失败,必须使用强类型名称,Type::General或Category::General if (t == Category::General) // 编译失败,必须使用Type中的General,Category和Type间不可以直接比较 cout << "General Weapon" << endl; if (t > Type::General) // 通过编译 cout << "Not General Weapon" << endl; if (t > 0) // 编译失败,无法转换为int类型,禁止隐式转换 cout << "Not General Weapon" << endl; if ((int)t > 0) // 通过编译,强制转换还是可以的 cout << "Not General Weapon" << endl; cout << is_pod<Type>::value << endl; // 1,C++11的强类型枚举仍是POD cout << is_pod<Category>::value << endl; // 1 return 0;}可以指定枚举成员的底层类型:
#include <iostream>using namespace std;enum class C : char { C1 = 1, C2 = 2};//若枚举值小于128,则可以char节省空间enum class D : unsigned int { D1 = 1, D2 = 2, Dbig = 0xFFFFFFF0U };int main() { cout << sizeof(C::C1) << endl; // 1 cout << (unsigned int)D::Dbig << endl; // 编译器输出一致,4294967280 cout << sizeof(D::D1) << endl; // 4 cout << sizeof(D::Dbig) << endl; // 4 return 0;}
2 智能指针
C++11的智能指针几乎是从Boost库的智能指针搬过来的,auto_ptr已经废弃了。unique_ptr表示不可以共享所指内存但是能通过move转让内存所有权。shared_ptr可以共享内存所有权,其采用引用计数,当计数为0时释放内存。weak_ptr是弱指针,其通常需要配合shared_ptr使用,其本身不会增加内存计数,但是可以通过提升lock操作变为shared_ptr若提升后的shared_ptr还存在则表明所管理的对象还存在,若提升后的shared_ptr为nullptr表明管理的对象已经不存在了。关于智能指针还是Boost的丰富些,除了这几个智能指针,boost还提供了管理数组的智能指针。
unique_ptr和shared_ptr的使用例子:
#include <memory>#include <iostream>using namespace std;int main() { unique_ptr<int> up1(new int(11)); // 无法复制的unique_ptr unique_ptr<int> up2 = up1; // 不能通过编译,这里是调用copy constructor,由于unique_ptr已经禁止copy constructor,但允许move constructor cout << *up1 << endl; // 11 unique_ptr<int> up3 = move(up1); // 现在p3是数据的唯一的unique_ptr,move constructor cout << *up3 << endl; // 11 cout << *up1 << endl; // 运行时错误 up3.reset(); // 显式释放内存 up1.reset(); // 不会导致运行时错误 cout << *up3 << endl; // 运行时错误 shared_ptr<int> sp1(new int(22)); shared_ptr<int> sp2 = sp1; cout << *sp1 << endl; // 22 cout << *sp2 << endl; // 22 sp1.reset(); cout << *sp2 << endl; // 22}weak_ptr和shared_ptr的例子:
#include <memory>#include <iostream>using namespace std;void Check(weak_ptr<int> & wp) { shared_ptr<int> sp = wp.lock(); // 转换为shared_ptr<int>,weak_ptr提升为shared_ptr if (sp != nullptr)//提升成功,说明管理的对象还存在 cout << "still " << *sp << endl; else//提升失败,管理的对象不存在了 cout << "pointer is invalid." << endl;}int main() { shared_ptr<int> sp1(new int(22)); shared_ptr<int> sp2 = sp1; weak_ptr<int> wp = sp1; // 指向shared_ptr<int>所指对象 cout << *sp1 << endl; // 22 cout << *sp2 << endl; // 22 Check(wp); // still 22 sp1.reset(); cout << *sp2 << endl; // 22 Check(wp); // still 22 sp2.reset(); Check(wp); // pointer is invalid}题外话:如何解决shared_ptr的循环引用?这里的循环引用指:假设对象A持有指向执行B的shared_ptr,对象B持有对象A的shared_ptr这样两个对象都不会被析构,解决的办法是:A持有B的shared_ptr,B持有A的weak_ptr
3 垃圾回收
C++11的垃圾回收仍没有成熟,所以该部分仅供参考娱乐,想了下还是不写该部分。现有的垃圾回收可能就是通过API指定内存可达(告诉垃圾回收器此部分内存不能回收),清除内存可达标志。
- C++11:提高类型安全
- C++11学习笔记5——提高类型安全
- 【C/C++】什么是类型安全
- C/C++的类型安全
- C/C++的类型安全
- C/C++的类型安全
- C/C++的类型安全
- C/C++的类型安全
- c#中泛型的类型安全与性能提高
- 【C语言提高32】数组类型
- C/C++不是类型安全的!
- 类型转换和类型安全(现代 C++)
- 【C语言提高33】数组指针类型定义
- 类型安全
- 类型安全
- 类型安全
- 类型安全
- JNI的提高,Java类型和C(C++)类型转换源代码
- android如何实现断点下载
- 读博经验之二
- Triangle
- 10420 - List of Conquests
- Asp.net TextBox只能输入数字
- C++11:提高类型安全
- 在html中获得本地时间的js代码,重要的是他能同步,而不是一时间的获取,然后以静态的方式体现
- 预祝大家平安夜圣诞节快乐
- 1、HelloWord-OC+UI
- 个人建站记录
- 机房收费系统—封装函数
- Auraro插件无法显示公式解决方法
- C语言实现 输入密码显示星号******
- Java调用SQL Server的存储过程详解