C++11的一些特性

1.断言是将一个需要为真的表达式放在语句中,在debug模式下检查一些逻辑错误的参数,C++中使用assert需要使用<assert.h>或者<cassert>头文件。有函数定义如下:

void  fun(int a[],int n)
{
assert(n>0);
//dosomething;
}

这样就可以检查n<=0的情况,如果遇到这种情况,程序会调用abort()函数而终止。

C++11提供了static_assert断言,它的函数原型接受两个参数,一个是断言表达式,一个是警告信息,可以用字符串表示。

static_assert(sizeof(int)==8,”64-bitmachine should follow this”);
int   main()
{
return  0;
}

可见,static_assert()比assert提供了更多的信息。另外,static_assert()用于在编译期做断言判断,而assert()用于在运行期间做断言判断。

2.__func__是C++99标准中预定义的标识符,功能是返回所在函数的名字,C++11标准中,__func__可以用于结构体中,如:

#include <iostream>
#include <cstdlib>
using  namespace std;
struct  Test
{
	Test():name(__func__){}
	const  char *name;
};
int  main()
{
	Test  t;
	cout<<t.name<<endl;
	return  0;
}

3.委派构造函数

class  A
{
public:
A(){init();}
A(int i):x(i){init();}
A(double d ):f(d){init();}
private:
void  init();
int  x;
double  f;
};

上面的代码中,三个版本的构造函数都调用了init()函数,有没有办法简化这段代码呢?

可以使用委派构造函数:

class  A
{
public:
A(){init();}
A(int i):A(){x=i;}
A(double d):A(){f=d;}
private:
void  init();
int  x;
double  f;
};

4.初始化列表

#include <vector>
#include <iostream>
using  namespace std;
int  main()
{
int  a[]={1,2,3};
int  b[]{1,2,3};
vector<int> c{1,3,5};
return  0;
}

C++11支持这样几种初始化的方式:

赋值符号 如int  a=1+2;

赋值符号加上初始化列表
int  a={1+2};

圆括号
int  a(1+2);

花括号加上初始化列表
int  a{1+2}

5.右尖括号的改进

template <class T>

classA

{};

vector<A<int>>v;//c++98编译失败,C++11编译成功

vector<A<int> > v;//C++98编译成功,C++11编译成功

6.auto类型推导

#include<iostream>
using  namespace std;
int main()
{
auto name=”world\n”;
cout<<”hello ”<<name<<enld;
return 0;
}

auto会自动推导出name的类型为constchar
*,然后在cout语句中输出

基于auto的上述特点,auto可以初始化复杂类型变量,可以支持泛型编程

7.for循环的改进

#include <isotream>
using namespace std;
void action(int &e)
{
	cout<<e<<endl;
}
int main()
{
int arr[3]={1,2,3};
int *p=arr;
for(;p<a+3;++p)
	cout<<*p<<endl;
for_each(arr,arr+sizeof(arr)/sizeof(arr[0]),action);//for_each
for(int &e:arr) //另外一种写法
{
	cout<<e<<endl;
}
for( auto e:arr) //auto自动类型推导
{
	cout<<e<<endl;
}
return 0;
}

8.智能指针

C++使用的是auto_ptr,在C++11中它被废弃了,取而代之的是unique_ptr,shared_ptr和weak_ptr,

unique_ptr的缺点是必须独自占有内存,不能直接用=来进行赋值,而且使用move方法赋值之后,指针会失去所有权。

#include <iostream>
#include <memory>
using namespace std;
int main()
{
unique_ptr<int >  p1(new int(1));
unique_ptr<int> p2=p1; //编译错,不能直接赋值
unique_ptr<int> p3=move(p1);
cout<<*p3<<endl;
cout<<*p1<<endl; //运行出错,p1的所有权已经交给了p3
return 0;
}

shared_ptr是表现的最像指针的智能指针。它使用引用计数来表示当前多少指针指向同一块内存,一个指针被释放,引用计数就会减少1,直到引用计数减少为0时,指针指向的内存才会真正的释放。

weak_ptr是作为shared_ptr的辅助,它本身不会引起引用计数的增加,它可以用来检验share_ptr的有效性。

#include <iostream>
#include <memory>
using  namespace std;
void  check(weak_ptr<int> &p)
{
shared_ptr<int>  t=p.lock();
if(t!=nullptr)
cout<<”ok”<<endl;
else
cout<<”error”<<endl;
}
int  main()
{
shared_ptr<int>  p1(new int(1));
shared_ptr<int>  p2=p1;
weak_ptr<int> wp=p1;
check(wp); //ok
p1.reset();
check(wp); //ok
p2.reset();
check(wp);
return  0;
}

9.空指针nullptr

C++98中,空指针NULL是一个宏,类似于#define
NULL0的形式,所以NULL本质上是个整型。C++11提出了nullptr代替NULL作为空的指针常量。nullptr相对于NULL有什么优势,可以看下这个函数重载的例子。

void f(int i){}

void  f(char *c){}

f(NULL)将会调用f(int)的版本,因为NULL是0

而f(nullptr)将会调用f(char*c),因为nullptr是nullptr_t类型的

nullptr与nullptr_t的关系:nullptr_t是指针类型,nullptr是nullptr_t类型的常量

nullptr_t的性质有:

nullptr_t类型数据可以隐式转换成任意一个指针类型

nullptr_t不能转换为非指针类型,

nullptr_t可以用于关系运算,但不能用于算术运算

#include <iostream>
#include <typeinfo>
using namespace std;
int  main()
{
char*p=nullptr; //转换为指针类型
int t=reinterpret_cast<int>(nullptr);//编译出错,nullptr_t类型不能转换为int
nullptr_tptr;
if(ptr==nullptr) //可以用于关系运算
	cout<<”nullptr”<<endl;
nullptr+=1;//编译出错,不能用于算术运算
return  0;
}

10.lamda函数

#include <iostream>
using namespace std;
int  main()
{
int  a=1;
int  b=2;
auto  fun=[=]()->int{return a+b;};
cout<<fun()<<endl;;
return  0;
}

auto  fun=[=]()->int{return a+b}定义了fun函数,它是lamda函数

lamda函数的定义方法如下:

[capture](parameter list) mutable ->return type {//do something;}

有关各个字段的含义这里不再赘述。

下面是lamda在stl中应用的一个例子:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
inline  void cmp(int i)
{
if(i>7)
	cout<<"larger  than  7"<<endl;
}
int  main()
{
int  a[10]={1,2,3,4,5,6,7,8,9,0};
vector<int>  v(a,a+10);
for(auto it=v.begin();it!=v.end();++it)
{
	if(*it>7)
		cout<<"largerthan 7"<<endl;
}
for_each(v.begin(),v.end(),cmp);
for_each(v.begin(),v.end(),[=](int i){
if(i>7)
	cout<<"largerthan 7"<<endl;
});
return  0;
}

上面的代码遍历一个容器vector,使用了三种方法,一是利用迭代器,逐个判断,二是利用仿函数,三是利用了lamda函数。

时间: 2024-10-21 02:11:41

C++11的一些特性的相关文章

Qt5 中对 C++11 一些新特性的封装

在 Qt5 中,提供更多 C++11 的特性支持,接下来我们将进行详细的说明. slots (槽) 的 Lambda 表达式 Lambda表达式 是 C++11 中的一个新语法,允许定义匿名函数.匿名函数可用于使用小函数作为参数,而无需显式的进行声明.之前可以通过编写函数指针来达到同样的目的. 在 Qt 4.8 中已经可在一些 QtConcurrent 函数中使用 Lambda 表达式了.但在 Qt5 中甚至可以通过 new connect syntax 来将 Lambda 表达式作为 slot

C++11 标准新特性:Defaulted 和 Deleted 函数

前两天写的铁字中提到了C++的删除函数,今天特地去网上查了查,转载了一篇不错的文章... 转载自 http://www.ibm.com/developerworks/cn/aix/library/1212_lufang_c11new/index.html C++11 标准新特性:Defaulted 和 Deleted 函数 本文将介绍 C++11 标准的两个新特性:defaulted 和 deleted 函数.对于 defaulted 函数,编译器会为其自动生成默认的函数定义体,从而获得更高的代

C++11 标准新特性: 右值引用与转移语义

C++ 的新标准 C++11 已经发布一段时间了.本文介绍了新标准中的一个特性,右值引用和转移语义.这个特性能够使代码更加简洁高效. 查看本系列更多内容 | 3 评论: 李 胜利, 高级开发工程师, IBM 2013 年 7 月 10 日 内容 在 IBM Bluemix 云平台上开发并部署您的下一个应用. 开始您的试用 新特性的目的 右值引用 (Rvalue Referene) 是 C++ 新标准 (C++11, 11 代表 2011 年 ) 中引入的新特性 , 它实现了转移语义 (Move

atitit.Oracle 9 10 11 12新特性attilax总结

atitit.Oracle 9  10 11  12新特性 1. ORACLE 11G新特性 1 1.1. oracle11G新特性 1 1.2. 审计 1 1.3. 1.   审计简介 1 1.4. 其他(大部分是管理功能) 2 2. Oracle 12c 的 12 个新特性 2 2.1. 2 Improved Defaults 增强了DEFAULT, default目前可以直接指代sequence了,同时增强了default充当identity的能力 2 2.2. Easy Top-N an

[.net 面向对象编程基础] (11) 面向对象三大特性——封装

[.net 面向对象编程基础] (11) 面向对象三大特性——封装 我们的课题是面向对象编程,前面主要介绍了面向对象的基础知识,而从这里开始才是面向对象的核心部分,即 面向对象的三大特性:封装.继承.多态. 1.封装概念 封装:每个对象都包含有它能进行操作的所有信息,这个特性称为封装.这样的方法包含在类中,通过类的实例来实现. 2.封装的优点 A.良好的封装能够减少耦合(比如实现界面和逻辑分离) B.可以让类对外接口不变,内部可以实现自由的修改 C.类具有清晰的对外接口,使用者只需调用,无需关心

C++11 委派构造函数特性怎么使用?

在代码开发中,C语言和C++都是基础语言,是很多web开发人员的入门级必学语言.但在C++98 中,类成员构造问题还存在一些问题,为此C++11提出了一些新特性. C++98中如果一个类有多个构造函数且要实现类成员构造,这些构造函数通常要包含基本相同的类成员构造代码.在最坏的情况下,相同的类成员构造语句被拷贝粘贴在每一个构造函数中. 基于C++98中的类成员构造问题,C++11新特性中,程序员可以将公有的类成员构造代码集中在某一个构造函数里,这个函数被称为目标构造函数.其他构造函数通过调用目标构

【C++11】新特性——Lambda函数

本篇文章由:http://www.sollyu.com/c11-new-lambda-function/ 文章列表 本文章为系列文章 [C++11]新特性--auto的使用 http://www.sollyu.com/c11-new-features-auto/ [C++11]新特性--Lambda函数 http://www.sollyu.com/c11-new-lambda-function/ 说明 在标准 C++,特别是当使用 C++ 标准程序库算法函数诸如 sort 和 find,用户经常

c++11的新特性

好奇心来源于下面的一段代码, 一个是unordered_map, 这是c++11新加的container. 另外还有unordered_set, unordered_multimap, unordered_multiset. 另外在for循环中, 可以使用下列形式: 1 for (auto &element : container) { 2 std::cout << element << std::endl; 3 } 还有一点就是变量的初始化, 请注意: int maxle

【cocos2dx开发技巧10】cocosStudio的集成以及c++11的新特性

转发,请保持地址:http://blog.csdn.net/stalendp/article/details/38880997 很长时间没有碰cocos2dx了,最近又用起来了,花了好几个小时重新熟悉了一下,发现很多新的特性值得用来写文章.好吧,先从最常用的开始.最近用windows,使用cocosStudio,就从这个开始吧,顺带介绍一下工程的创建,以及c++11的特性.以前开发使用cocosBuilder开发界面(相关集成见这篇文章). 准备工作 1)准备NDK.andrdoid-SDK,V

stout代码分析之九:c++11容器新特性

stout大量使用了c++11的一些新特性,使用这些特性有利于简化我们的代码,增加代码可读性.以下将对一些容器的新特性做一个总结.主要两方面: 容器的初始化,c++11中再也不用手动insert或者push_back来初始化了 容器的遍历,c++11中再也不用使用冗长的迭代器遍历了 让我们一睹为快吧: #include <map> #include <string> #include <iostream> #include <vector> int main