IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C++11新特性】| 【01】保证稳定性和兼容性 -> 正文阅读

[C++知识库]【C++11新特性】| 【01】保证稳定性和兼容性

一、简介

1、设计目标

- 让C++成为更好的适用于系统开发及库开发的语言;
- 让C++成为更易于教学的语言;
- - 保证语言的稳定性,以及C++03、C语言的兼容性;

2、C++11的增强

- 通过内存模型、线程、原子操作等来支持本地并行编程;
- 通过统一初始化表达式、auto、declytype、移动语义等支持泛型编程;
- 通过constexpr、POD等来支持系统编程;
- 通过内联命名空间、继承构造函数和右值引用等来支持库的构建;

3、新增关键字

- alignas
- alignof decltype
- auto
- static_assert
- using
- noexcept
- nuillptr
- constexpr
- thread_local

二、保证稳定性和兼容性

1.1 保持与C99兼容

- C99的预定义宏;
- __func__预定义标识符
- _Pragma操作符
- 不定参数宏定义以及__VA_ARGS
- 宽窄字符串连接

1.2 预定义宏

__STDC_HOSTED__:是否包含完整标准C库;
__STDC__:编译器的实现是否和C标准一致;
__STDC_VERSION__:C标准版本;
__STDC_ISO_10646:C++编译环境符合的版本ISO/IEC 10646标准;

__func__:返回当前函数的名字,允许使用与class和struct;
	- 不允许用于默认参数;

_Pragma操作符:该操作符与#pragma功能相同(#pragma once=_Pragma("once"));
	- 该操作符可以在宏中进行展开,具有更大的灵活性;

__VA_ARGS__:指宏定义的最后一个参数为省略号代替的字符串;

char_t转wchar_t:C++11会自动将窄字符转成宽字符串;

__cplusplus:C++编译器给程序的每个函数换一个独一无二的名字,由于C++中有函数重载;
	如果声明了一个函数,则经过编译器可能改变;在C++编译器下,当调用C函数时,要禁止名变换;

1.3 long long整型

long long==> long long(LL/ll)和unsigned long long(ULL);

1.4 扩展的整型

五种标准的有符号整型:
- signed char
- short int
- int
- long int
- long long int
以上都有无符号整数版本对应,且和符号有相同的存储空间大小;

【整型提升】:当类型不匹配时会往`等级高`、`无符号`提升;
- 长度达的等级高;
- 长度相同,标准整型的等级高于扩展类型;
- 有符号和无符号相同;

1.5 静态断言

断言

判断该判断式(状态)是否为真,迫使参数异常的时候退出程序;
- 可以使用NDEBUG来禁用asert宏;

静态断言

assert再程序运行时才起作用,当我们需要再编译时做一些断言时,此时需要用到静态断言;
系统库没有提供静态断言供我们使用,故我们通过语言的规则来实现:
- 利用【除0】的特性;
#define assert_static(e)\
		enum{assert_static__ = 1/(e)};
后来C++11引入static_assert,接收两个参数,【常量表达式、警告信息】;
可以独立于任何调用之外运行;
【注意】表达式中不能有参数变量;

1.6 noexcept修饰符与操作符

与断言不同,异常用于逻辑上可能发生的错误,用来保证应用程序的安全;
C++11中弃用了throw,被noexcept取代;
当它修饰函数时,则函数不会抛出异常,若修饰的函数抛出异常(有效制止异常的传播与扩散),则直接终止,效率高于throw;
【两种形式】:
- 修饰符:直接再函数声明后添加,即该函数不会抛出异常;
- 操作符:也是用于函数声明后,(bool)内为常量表达式,为true时不会抛出异常,
void test() noexcept;
void test() noexcept(true);
template<class T>
void test() noexcept(noexcept(T())) {}

- C++11中为了保证析构函数的安全,默认再类析构中添加noexcept(true);

1.7 快速初始化成员变量

在C++98中,如果静态成员不满足常量性,则不可以直接的声明,即使初始化const static也只能在int和enum两种类型;
如:
class A{
private:	
	int a = 1;					// ×  
	static int b = 1;			// ×  
	static const doube c = 1.1; // ×  
	static const int d = 1;		// √
};
在C++11中,允许使用{}=对非静态成员变量初始化,但对就地初始化两者并非等价,要使用{}struct C {
    C(int i) : c(i) {}
    int c;
};

class A{
private:
	C c(1);	// ×
    C c{2};	// √
};

初始化列表与就地初始化

class A{
public:
    A(int a, string name) : m_a(a), m_name(name) {
        cout << m_a << " " << m_name << endl;
    }
private:
    int m_a {0};
    string m_name{"123"};
};

void test_init() {
    A a(10, "xiao");
}
经测试告诉我们,初始化列表与就地初始化并不冲突,且初始化列表总是优先于就地初始化;
当然使用就地初始化可以减轻我们对构造函数中对成员变量的初始化;

1.8 非静态成员的sizeof

C++11中sizeof可以对非静态成员变量使用sizeof操作符;
在C++98中,如果对类成员获取大小 sizeof(((class*)0)->hand);

1.9 扩展friend语法

在C++11中友元声明可直接`friend 名称`可直接省略class,或可使用别名;
增加了新功能,能在类模板中声明友元;
template<class T> class A {
	friend T;
};

1.10 final/overide控制

final:不然该函数在子类中被重写;
override:防止父类中的虚函数在子类中要被重写时,错该函数的名称或参数;

1.11 模板函数的默认模板参数

C++11中模板可以有默认的参数,且编译器能够自动推导实参中的类型;
默认模板参数的作用好比函数的默认形参;当然默认模板参数与函数类似,需要遵循从右往左的规则;
如果可以从函数实参中推导出类型,则默认模板参数就不会被使用;
默认模板参数通常时需要跟默认参数一起使用;
template<class T, class U = double >
void f(T t = 0, U u = 0);

void g() {
    f(1, 'c'); // <int, char>(1, 'c')
    f(1);         // <int, double>(1, 0)
    f();            // ×
    f<int>();       // f<int, double>(0, 0)
    f<int,char>();  // f<int, char>(0, 0)
}

1.12 外部模板

类似于外部变量;
当一个头文件中:template<typename T>void func(T) {}
分别用在cpp1:void test1() { func(3); }
分别用在cpp2:void test2() { func(4); }
由于使用模板一致,故其编译时两个目标文件中会有两份相同的func<int>(int);

如何避免上述代码重复

由于代码重复会导致编译器的增加编译时间和链接时间;
在链接过程中,链接器通过一些编译器辅助的手段将重复的模板函数代码删除,只保留一个副本;
解决该问题,类似于使用外部变量;

我们只需声明
template void func<int>(int);即可人编译器实例化一个版本
若使用外部模板
则只需在声明添加一个extern;

分别用在cpp1:template void func<int>(int);// 实例化  void test1() { func(3); }
分别用在cpp2:extern template void func<int>(int);// 外部声明 void test2() { func(4); }
也可将外部模板声明放置与头文件中,即包含该头文件即可共享这个外部模板声明;

注意事项

- 如果外部模板声明于某个编译单元,则显示实例化必须在另一个/同一个编译单元中;
- 外部模板声明不用于一个静态函数,由于静态函数没有外部链接属性;
- 当项目较大时,才建议这样使用;

1.13 局部和匿名类型作为模板实参

template<typename T> class X{};
template<typename T> void TempFun(T t) {};
struct A{} a;
struct {int i;}b;
typedef struct {int i;}B;

void Func() {
    struct C{} c;
    X<A> x1;
    X<B> x2;
    X<C> x3;

    TempFun(a);
    TempFun(b);
    TempFun(c);
}
C++11支持用普通的全局结构体、匿名的全局结构体、局部的结构体作为参数传给模板;
【注意】匿名类型的声明不能在模板实参的位置	TempFun<struct {int a; }> t,需要使用其别名;
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-08 07:51:17  更:2022-05-08 07:51:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 0:56:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码