C++11常用特性学习-保证稳定(_func_/long long/static_assert/final/override)
来源:互联网 发布:印刷厂软件 编辑:程序博客网 时间:2024/06/10 02:18
C++11常用特性学习
C++11标准为C++编程语言的第三个官方标准,正式名叫ISO/IEC 14882:2011 - Information technology – Programming languages – C++。 在正式标准发布前,原名C++0x。2014年8月18日,经过C++标准委员投票,C++14标准获得一致通过。目前C++17已经发布指导文件,增加了许多语言特性,进一步完善C++语言支持和特性(作死的道路越走越远,规范的API,统一类库和编译特性都木有啊);
学习要了解的有:
- 新的算法和类库;
- auto和decltype类型推导的关系;
- 移动语义,以及右值引用是如何解决转发问题;
- default/delete函数以及override是怎么回事;
- 异常描述符和noexcept;
- 原子类型和新的内存模型;
- C++11并行编程;
主要参考:《深入理解C++11新特性解析与应用》以及随笔分类 - C++11学习和每个C++开发者都应该使用的十个C++11特性、开发者都应该使用的10个C++11特性、C++11新特性等博客。本文只学习C11常用并且在VS,GCC和Clang等编译器都已经较好的支持并且常用和易于理解的部分功能。
- C11常用特性学习
- 编译器的选择
- 保证稳定和兼容的新特性
- _func_预定义标识符
- long long整型
- 断言运行时与预处理时
- finaloverride控制
编译器的选择
C11准于2011年发布并出版,出版时,主流编译器并不支持C11的所有特性,目前(2015年11月)公司主流项目使用的编译器VS12 (Visual Studio 2012)、g++ 4.7和Clang 3.1对C++的支持力度各部相同;但对常用的auto等常用功能都有了支持,具体支持情况见:C++11各编译器支持情况对比;目前VS13(Visual Studio 2013)、gcc 4.8.1已经支持C11大部分特性。VS15(Visual Studio 2015)支持 C++11/14/17 功能(现代 C++)和GCC 5.2 已经开始支持C17功能。可以选用Vs2013和gcc4.8.1来学习。(后记:MD,VS2013 C11预览版BUG满天飞,VS15版安装包5个G,搞死人啊!!)
C++之父Bjame Stroustrup说C11就像一个新语言,的确,C11核心已经发生了巨大的变化,它现在支持Lambda表达式,对象类型自动推断,统一的初始化语法,委托构造函数,deleted和defaulted函数声明nullptr,以及最重要的右值引用。C11中值得关注的几大变化:
◆ Lambda表达式
◆自动类型推断和decltype
◆统一初始化语法
◆ Deleted和Defaulted函数
◆ nullptr
◆ 委托构造函数
◆ 右值引用
上述特性在文章:C++11它就像一个新语言、掀起C++ 11的神秘面纱提供的连接中有详细的探讨。相对于C++98/03来说,主要是为了增强和优化如下几点:
◆通过内存模型、线程、原子操作等支持本地并行编程(Native Concurrentcy);
◆通过统一初始化表达式、auto、declytype、移动语义等来统一对泛型编程的支持;
◆通过constexpr、POD(概念)等更好支持系统编程;
◆通过内联命名空间、继承构造函数和右值引用等、以更好的支持库的构建。
注:通过以上辛苦的工作,C11朝着“恐怖编程语言泛型”前进;
保证稳定和兼容的新特性
_func_预定义标识符
func预定义标识符表示函数的名字;
#include <string>#include <iostream>using namespace std;const char* hello() { return __func__; }const char* world() { return __func__; }int main(){ cout << hello() << ", " << world() << endl; // hello, world}
我们定义了两个函数hello和world。利用func预定义标识符,我们返回了函数的名字,并将其打印出来。事实上,按照标准定义,编译器会隐式地在函数的定义之后定义func标识符。
void FuncFail( string func_name = func) {};// 无法通过编译
这是由于在参数声明时,func还未被定义。
long long整型
long long整型有两种:long long和unsigned long long。在C++11中,标准要求long long整型可以在不同平台上有不同的长度,但至少有64位。我们在写常数字面量时,可以使用LL后缀(或是ll)标识一个long long类型的字面量,而ULL(或ull、Ull、uLL)表示一个unsigned long long类型的字面量。比如:
long long int lli = -9000000000000000000LL;
unsigned long long int ulli = -9000000000000000000ULL;
与long long整型相关的一共有3个:LLONG_MIN、LLONG_MAX和ULLONG_MIN,它们分别代表了平台上最小的long long值、最大的long long值,以及最大的unsigned long long值。
#include <climits>#include <cstdio>using namespace std;int main() { long long ll_min = LLONG_MIN; long long ll_max = LLONG_MAX; unsigned long long ull_max = ULLONG_MAX; printf("min of long long: %lld\n", ll_min); // min of long long: -9223372036854775808 printf("max of long long: %lld\n", ll_max); // max of long long: 9223372036854775807 printf("max of unsigned long long: %llu\n", ull_max); // max of unsigned long long: 18446744073709551615}
断言:运行时与预处理时
在C++中,程序员也可以定义宏NDEBUG来禁用assert宏。
#include <cassert>using namespace std;// 一个简单的堆内存数组分配函数char * ArrayAlloc(int n) { assert(n > 0); // 断言,n必须大于0 return new char [n];}int main (){ char* a = ArrayAlloc(0);}
这对发布程序来说还是必要的。因为程序用户对程序退出总是敏感的,而且部分的程序错误也未必会导致程序全部功能失效。那么通过定义NDEBUG宏发布程序就可以尽量避免程序退出的状况。而当程序有问题时,通过没有定义宏NDEBUG的版本,程序员则可以比较容易地找到出问题的位置。事实上,assert宏在中的实现方式类似于下列形式:
#ifdef NDEBUG# define assert(expr) (static_cast<void> (0))#else...#endif
可以看到,一旦定义了NDBUG宏,assert宏将被展开为一条无意义的C语句(通常会被编译器优化掉)。但是assert是在运行时进行断言,我们希望在有些时候编译的过程中就能发现某些问题,从而方便排错。
断言assert宏只有在程序运行时才能起作用。而#error只在编译器预处理时才能起作用。有的时候,我们希望在编译时能做一些断言。在一些C++的模板的编写中,我们希望对参数进行初步判断,如保证两种类型的长度一致,这样bit_copy才能够保证复制操作不会遇到越界等问题。这种情况下,正确产生断言的时机应该在模板实例化时,即编译时期。事实上,利用语言规则实现静态断言的讨论非常多,比较典型的实现是开源库Boost内置的BOOST_STATIC_ASSERT断言机制(利用sizeof操作符)。
在C++11标准中,引入了static_assert断言来解决这个问题。static_assert使用起来非常简单,它接收两个参数,一个是断言表达式,这个表达式通常需要返回一个bool值;一个则是警告信息,它通常也就是一段字符串。如:
template <typename t, typename u> int bit_copy(t& a, u& b){ static_assert(sizeof(b) == sizeof(a),"the parameters of bit_copy must have same width.");};
这样的错误信息就非常清楚,也非常有利于程序员排错。而由于static_assert是编译时期的断言,其使用范围不像assert一样受到限制。
final/override控制
Java语言使用了final关键字来阻止函数继续重写。final关键字的作用是使派生类不可覆盖它所修饰的虚函数。C11也采用了类似的做法,
struct Object{ virtual void fun() = 0;};struct Base : public Object { void fun() final; // 声明为final};struct Derived : public Base { void fun(); // 无法通过编译};// 编译选项:g++ -c -std=c++11 2-10-2.cpp
在C++11中为了帮助程序员写继承结构复杂的类型,引入了虚函数描述符override,如果派生类在虚函数声明时使用了override描述符,那么该函数必须重载其基类中的同名函数,否则代码将无法通过编译。防止在子类重载时出现参数和拼写错误。
- C++11常用特性学习-保证稳定(_func_/long long/static_assert/final/override)
- C++11新特性学习笔记—long long
- C++11中__func__,__cplusplus,long long类型,static_assert,noexcept,快速初始化成员变量用法
- Long
- c++11 特性 final与override关键字
- C++11 特性:显式 override 和 final
- c++11新特性--static_assert
- c++11新特性--static_assert
- private static final long serialVersionUID
- private static final long serialVersionUID
- private static final long serialVersionUID
- C/C++: short , int , long , long long数据类型选用
- C++11新特性学习笔记—final和override关键字
- C++:int ,long , long long类型的范围
- C/C++中int、long、long long取值范围
- MFC/C/C++ CString 转 int\double\long\long long
- C语言中int、long int、long long的区别
- C语言中int、long int、long long的区别
- HDU 2253 Longest Common Subsequence Again
- EEG 学习记录
- 黑马程序员——C语言——数组
- delphi中需要熟悉的知识点
- POJ-2479-Maximum sum-双向dp-2次连续区间和
- C++11常用特性学习-保证稳定(_func_/long long/static_assert/final/override)
- 结构决定算法
- SSL构建单双向https认证!https部署及注意事项!
- 阿里云window服务器检查恶意攻击方法
- 使用ExpandableListView实现一个时光轴
- UI学习 第四章 UIImage UIImageView 手势
- statement with no effect 解决
- 使用自定义的xib文件进行启动页面的加载
- AVL树