【C/C++】C++11新特性
2015-06-02 22:41
323 查看
auto
自动推导类型。auto i = 10; std::cout << i << std::endl; double x = 12.34; auto *y = new auto(x); std::cout << *y << std::endl;
decltype
可以获取变量或值的类型名称,替换源码中的调用。int x = 0; decltype(x) y = x;
nullptr
空指针,指向地址0x000000的指针。与NULL的区别是,NULL是0的别名,原型为:#define NULL 0,调用NULL的地方相当于直接替换为0。智能指针
#include <stdlib.h> #include <iostream> #include <memory> void main(){ // 建议在for前后断点观察进程占用内存 for (int i = 0; i < 1000000; ++i) { double* p = new double; std::auto_ptr<double> ap (p); //C++98中的智能指针,依赖一个原生指针。在块结束时释放指针指向内存,相当于把堆当栈使用。 } for (int i = 0; i < 1000000; ++i) { std::unique_ptr<double> ap (new double); //C++11中的智能指针,可直接使用原生指针初始化,当指针不被引用时释放指针指向内存。 } system("pause"); }
高级for
int arr[] = {1,2,3,4,5}; for( int i : arr ){ std::cout<<i<<std::endl; }
lambda表达式
lambda式的作用类似Java中的创建一个匿名函数对象。这样就可以省去定义很多只有一处地方使用的函数。lambda表达式格式:
[ 可访问外部变量列表 ]( 参数列表 ) ->返回值类型 { 函数体 }
std::array<int>(5) arr = {1,2,3,4,5}; int a = 1; int b = 2; //1.访问指定外部变量的右值(右值在寄存器,不在内存,不存在地址,所以不能执行赋值操作) for_each(arr.begin(), arr.end(), [ a, b ] ( int & i ) { std::cout<<a<<std::endl; std::cout<<b<<std::endl; //a = b; //error }) //2.访问所有外部变量的右值 for_each(arr.begin(), arr.end(), [ = ] ( int & i ) { std::cout<<a<<std::endl; std::cout<<b<<std::endl; }) //3.访问指定外部变量的左值 for_each(arr.begin(), arr.end(), [ &a, &b ] ( int & i ) { a = b = i; std::cout<<a<<std::endl; std::cout<<b<<std::endl; }) //4.访问所有外部变量的左值 for_each(arr.begin(), arr.end(), [ & ] ( int & i ) { a = b = i; std::cout<<a<<std::endl; std::cout<<b<<std::endl; }) //5.定义一个有返回值的lambda表达式 auto fun = [ ] ( int & a , int & b) ->int { return a+b; }) int result = fun(arr[0], arr[0]);
tuple
tuple是一个多元组,可以包含多个不同类型的数据。// tuple example #include <iostream> // std::cout #include <tuple> // std::tuple, std::get, std::tie, std::ignore int main () { std::tuple<int,char> foo (10,'x'); auto bar = std::make_tuple ("test", 3.1, 14, 'y'); std::get<2>(bar) = 100; // 访问tuple中的元素 int myint; char mychar; std::tie (myint, mychar) = foo; // unpack elements std::tie (std::ignore, std::ignore, myint, mychar) = bar; // unpack (with ignore),std::ignore用于忽略指定位置的元素 mychar = std::get<3>(bar); std::get<0>(foo) = std::get<2>(bar); std::get<1>(foo) = mychar; std::cout << "foo contains: "; std::cout << std::get<0>(foo) << ' '; std::cout << std::get<1>(foo) << '\n'; return 0; }
可变参数列表
#include<cstdarg> //用于处理可变参数列表的库 template<typename T> T sum(int count, T data1, ...) // data1用于限定可变参数列表至少需要一个参数 { va_list arg_ptr; //定义可变参数列表指针 va_start(arg_ptr, count); //初始化可变参数列表,限定从count后面开始 T total = 0; for(int i=0; i<count; ++i){ total += va_arg(arg_ptr, T); // 取可变参数列表中的参数进行累加 } va_end(arg_ptr); //结束可变参数列表指针的使用 return total; }
可变参数模板
#include<iostream> template<typename... Arguments> void func(const Arguments&... args) { const unsigned size= sizeof...(Arguments); // sizeof...操作符可获取可变参数列表的参数个数 std::cout << size<< std::endl; printf(args...); } void main(){ func("%d%d%d%d",1, 2, 3, 4); }
使用{}初始化
在C++11之前,只有数组可以使用{}初始化。C++11之后stl中的容器也可以使用{}初始化了。//C++11 之前: std::map<int,string> map; map[1] = "a"; map[2] = "b";
//C++11之后: std::map<int,string> map = { {1,"a"}, {2,"b"} };
类成员变量初始化默认值
在C++11之前,类的成员变量如果想初始化一个默认值只能通过构造函数去初始化,但如果有多个构造函数,这时初始化就变得麻烦了,每个构造都需要初始化,或者通过一个构造调用另一构造方式初始化。C++11之前
class A{ private: int i; public: A():i(1){} //初始化i为1 A(string str):i(1){} //初始化i为1 };
或
class A{ private: int i; public: A() :i(1){} //初始化i为1 A(string str):A(){ } //调用空构造,初始化i为1 };
在C++11之后
class A{ private: int i = 1; //给成员变量设置默认初始值 public: A(){} A(string str){} };
相关文章推荐
- 二叉树各种相关操作(建立二叉树、前序、中序、后序、求二叉树的深度、查找二叉树节点,层次遍历二叉树等)(C语言版)
- C++代码规范
- 对C++中迭代器的辅助函数的认识
- c语言获取本地时间
- RSA加密算法(C语言实现)
- 浅谈C++容器( 三)
- 【C语言】巴斯卡三角问题
- 详解C++右值引用
- Cpp primer<<学习函数-实参类型转换、指向函数的指针_3
- [c++] random number
- C++ 初识虚函数
- 黑马程序员——C语言基础——结构体相关练习
- c++ 二维数组名为何取值后与原地址相同
- C++怎么用二维数组作为形参传入
- C语言初探 之 printf压栈顺序(printf("%d %d %d %d %d %d\n",a++, ++a, a++, ++a, a++, ++a ))
- C语言学习-01第一个C语言程序
- 使用C++的string实现高精度加法运算
- 使用C++的string实现高精度加法运算
- C++ volatile关键字
- C语言跳表(skiplist)实现