c++11设计理念——保证稳定性和兼容性

文章目录

  • 保持与c99兼容
  • long long 整型
  • 扩展的整型
  • 宏__cplusplus
  • 静态断言
  • noexcept修饰符和noexcept操作符
  • 快速初始化成员变量
  • 非静态成员的sizeof
  • 扩展的friend语法
  • final / override 控制
  • 模板函数的默认模板参数
  • 显示的实例化和外部模板的声明
  • 局部和匿名类型做模板实参

根据设计理念对c++11新特性进行划分

保持与c99兼容

c++11对c99特性的支持纳入了新标准中

  • c99中的预定义宏
  • __func__预定义标识符
  • __Pragma操作符
  • 不定参数宏定义以及__VA_ARGS__
  • 宽窄字符串连接
    预定义宏
    __ STDC_HOSTED __:编译器的目标系统环境中包含完整的标准C库,宏定 义是1 ,否则是0
    __ STDC __: C编译器通常用这个宏的值来表示编译器的实现是否和C标准一致。
    __ STDC_VERSION __: 表示所支持的C标准的版本4
    __STDC_ISO_10646 _:

__ func __ 预定义标识符:返回所在函数的名字 不过将__func__标识符作为函数参数的默认值是不允许的。这是由于在参数声明的时后,__ func __ 还没定义。
__ Pragma 操作符
#pragma once 相当于

#ifndef THIS_HEADER
#define THIS_HEADER
// 一些头文件的定义
#endif
相当于
_Pragma(“once”); #pragma 不能再宏中展开,所以_Pragma的力灵活性更高
变长参数的宏定义和 __ VA_ARGS __:
变长参数的宏定义:指的是在宏定义中参数列表的最后一个参数为省略号…
而后者可以替换省略号所代表的字符串
宽窄字符串的连接
c++11表准的编译器会将窄字符串转换成宽字符串,然后再与宽字符串进行连接。

long long 整型

c++最大整型的改变就是多了long long
unsigned long long 和 unsigned long long int 是等价的
long long 整型可以在不同的平台有不听的长度,但至少是64位
要知道平台long long 大小的方法就是查看 ()中的宏
有三个:
LLONG_MIN 最小long long 值
LLONG_MAX 最大 long long 值
ULLONG_MIN 最小 unsigned long long 值

扩展的整型

c++11中一共之定义了5种标准的有符号整型

  • signed char
  • short int
  • int
  • long int
  • long long int
    c++11规定:扩展的整型必须和标准类型一样,有符号类型和无符号类型占用同样的大小的存储空间
    c++是一种弱类型语言,当运算、传参等类型不匹配的时候,整型间发生隐式的转换,这个过程是整型的提升。
    进行隐式的整型转换时候,低等级向高等级 有符号转换成无符号
    原则是
    长度越大的整型等级越高 long long int 高于 int
    长度相同的情况下,标准整型 等级高于扩展整型 long long int 高于_ int64
    相同大小的有符号类型和无符号类型的等级相同,long long int 和 unsigned long long int

宏__cplusplus

__ cplusplus 这个宏通常被定义为一个整型值,随着标准的变化,一般会是一个比以往标准中更大的值
extern"c" 这样的做法是成为了c与c++中混用头文件的典型做法
连接器可靠的对两种类型的目标文件进行链接。
#ifdef __ cplusplus
extern “C”{
#endif
//一些代码
#ifdef __ cplusplus
}
#endif

静态断言

断言: 是将一个返回值总是需要为真的判别式放在语句中,比如一个函数总是输入在一定范围内的参数,对参数使用断言。
优点:通常断言能够帮助程序开发者快速定位那些违反了某些前提条件的程序错误。
在< cassert>或头文件中提供 assert宏
定义NDEBUG 来禁用assert宏
断言assert只有在程序运行是才有效
为了解决如何在编译时断言,则引出了所谓的“”“静态断言”
可以采用三种方法实现静态断言:
1.利用除0会导致编译器报错这个特性来实现静态断言
#define assert_static(e)
{
do {
enum {assert_static__ =1/(e) };
}while(0)

2.Boost库内置的BOOST_STATIC_ASSERT 输出的信息主要是sizeof错误
3. static_assert 接收两个参数 :断言表达式(必须是常量表达式) ,通常返回一个bool值 ;一个则是警告信息 写一句警告的话,放在""里面
如果程序员要的是运行时的检查,用assert宏就行

noexcept修饰符和noexcept操作符

c++11中弃用了 throw() 动态异常声明
若表示不会抛出异常,则用noexcept()取代了throw()
如果noexcept()表示抛出了异常,编译器可以直接选用std::terminate()函数来终止运行,这比异常机制throw()的效率高,因为异常机制带来额外的开销,比如函数抛出异常,会导致函数栈被依次的展开。
noexcept()修饰符有两种形式,
直接在函数声明后面加上关键字 noexcept
或者后面在加上 (常量表达式)
若常量表达式转换成的bool类型值为true 说明 不会抛出异常,false 抛出异常
若用于模板,很好的支持了泛型编程
一个类析构函数不应该抛出异常,c++11默认将delete函数设置成 noexcept 可以提高应用程序的安全性。
c++11中让类的析构函数默认为noexcept(true)的,若显示的指定就会失去默认值。

快速初始化成员变量

c++98中“就地声明”。
用= 初始化类中静态成员变量,如果静态成原变量不满足常量性,则不可以就地声明,而且即使是常量的静态成原也只能是整型或者枚举型才能就地初始化。
c++11中,允许非静态成员使用= 或{ }进行就地的非静态成原的初始化。初始化列表被保存下来,是否能把两者结合使用呢?答案是可以的。只不过初始化列表 的效果总是优先于就地初始化。

非静态成员的sizeof

在c++98中对非静态成员变量使用sizeof是不能通过编译的。
在c++11中可以使用。

扩展的friend语法

c++11对friend 关键字做了一些改进
在c++11中声明一个类为另外一个类的友元时,不在需要使用class 关键字
使用内置类型int 作为模板参数的时候,people会被实例化为一个普通的没有友元定义的类型。
使用using定义类型别名和使用typedef的定义类的别名是完全一样的。

final / override 控制

final关键字作用是使派生类不可覆盖他所修饰的虚函数
c++中重载有一个特点,基类声明为virtual函数,之后的重载版本都不需要再声明重载函数为virtual 。编译器可忽略。
虚函数描述符:override
派生类在虚函数声明时使用override描述符,那么该函数必须重载其基类中同名函数,否则代码将无法通过编译。

模板函数的默认模板参数

函数末班参数的选择总是由函数的实参推导而来的。

显示的实例化和外部模板的声明

c++11是对外部模板 模板性能上的一个改进 extern
外部模板声明 和显式实例化差不多,只是多了extern关键字
在使用外部模板时注意:
如果外部模板声明在某个编译单元中,那么与之对应的显式实例化必须出现在另一个编译单元中或者同一个编译单元的后续代码中,外部模板声明不能用于一个静态函数,可以用于类静态成员函数,因为静态函数没有外部链接属性。
c++11中模板的显示实例化定义 、外部模板声明 和使用 对比 全局变量的定义,外部声明和使用 的方式 ,不过相比于外部声明变量,外部末班声明不会有什么问题。外部模板定义算作是一种针对编译器的编译时间和空间的优化手段。

局部和匿名类型做模板实参

要使用匿名结构体作为模板参数,则可通过对匿名结构体做别名来实现。也可以用c++11独有的decltype完成相应的功能。

你可能感兴趣的:(c++11,c++)