C++11新特性

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){} 
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值