什么是C++11?

一句话C++11是最新的C++标准,在2011年发布,所以叫C++11。在新的标准出现前,我们一直在用的是C++98,可想而知这份标准是1998年发布的,之后再2003年最过小的修改发布了C++03。C++之父说C++11就像一门全新的语言,这份标准孕育了10年之久,是它的匠心之作。听起来C++11很牛,那它带来了哪些特性呢?让我从一个普通的不能再不普通的程序员角度去解读。

从哪里能了解到C++11

  • 维基百科C+11
  • 买第五版的《C++ primer》,用C++11重新编写。(我看的就是这个)
  • 还有一些关于C++11的书是英文版的,《C++11程序设计》第四版(C++之父写的),《C++标准库:自学教程与参考手册》第二版。
  • 还有网络上关于C++11特性的闲言琐语。

看过之后还能记住的C++11特

  • 万能关键字auto

但我们定义一个类型时,应该首先使用它,短小方便。特别是配合STL中的容器使用时让人感觉到得心应手。

auto int_variable = 12;

auto double_variable = 12.5;

auto int_ptr = &int_variable;

std::vector<int> stl_vector = { 1, 2, 3 }; // 初始化列表

auto beg = stl_vector.begin();// 为迭代器类型

auto end = stl_vector.end();

auto stl_vector2(stl_vector);

  • 自动类型推导decltype。

它可以推导出变量,表达式,函数指针的类型。

decltype (stl_vector) stl_vector3;

int(*ptr_compare) (int*, int*)=Compare; //指向Compare

decltype(Compare) ptr_compare2;

/*auto和decltype配合使用*/

template<class T1, class T2>

auto Min(T1 t1, T2 t2)->decltype(t1+t2)

{

return (t1 < t2 ? t1 : t2);

}

  • 列表初始化

列表初始化统一了C++的初始化方式,当初始化对象或者给对象赋新值时。

/*变量列表初始化*/

int c{ 0 };

double d = { 0.65 };

auto s = { "hello,world! " };

/*容器列表初始化*/

std::list<int> set= {1,2,3};

decltype(set) set2{ set };

/*类中变量列表初始化*/

class Object

{

public:

Object() :a{ 0 }, b{0.0}{}

private:

int a;

double b;

};

  • 范围for循环

/*复制容器中的元素*/

for (auto e : set)

{

std::cout << e << "\t";

}

/*引用容器中的元素*/

for (auto & e : set2)

{

e = 0;

std::cout << e << "\t";

}

/*应用字符串*/

for (auto e : str)

{

std::cout << e << "\t";

}

  • constexpr变量

如果你认定变量是一个常量表达式,那就把它声明成constexpr类型。编译器会判断它是否为一个常量。constexpr还可用来定义常量函数。Constexpr函数的参数和返回值必须是字面值类型,函数体内只有一条return语句。

/*constexpr变量*/

constexpr int iconst = 25;

constexpr double dconst = 0.25;

/*constexpr 函数*/

constexpr int new_sz(){ return 42; }

constexpr size_t scale(size_t cnt) { return new_sz()*cnt; }

int arr[scale(2)];

  • 类型别名声明

新标准使用using声明类型别名,相比于typedef来说,using有更强的灵活性,类型中可以模板typdef不行。

using ivec = std::vector<int>;

using citer = std::vector<int>::const_iterator;

  • 类中的变量初始化

/*类内初始化,内置类型和自定义类型*/

  1. class Screen

    {

    public:

    Screen() = default;

    using pos = std::string::size_type;

    Screen(pos ht, pos wd, char c) :height(ht), width(wd), contents(ht*wd,c)

    {}

    private:

    pos cursor = 0;

    pos height = 0, width = 0;

    std::string contents;

    };

    class WindowMsg

    {

    public:

    private:

    std::vector<Screen> screens{ Screen(24, 80, ' ') };

    std::string window_name{"hello world"};

    double a = 1.0;

    };

  • 类中的default、delete、override和final

    /*抽象类*/

    class Shape

    {

    public:

    Shape() = default;

    Shape(const Shape& shape) = delete;

    Shape& operator=(const Shape& shape) = delete;

    virtual void Draw() const = 0;

    private:

    };

    /*具体类*/

    class Circle:public Shape

    {

    public:

    Circle(double new_radius) :radius(new_radius){}

    virtual void Draw() const override final{}

    private:

    double radius=0.5;

    };

  • nullptr指针

更安全,没什么好说的。使用NULL有时候会出现问题。

  • 智能指针

智能指针是最应该去学习的特性,一句话智能指针自动内存管理,减少内存泄露的可能性。两种指正指针,shared_pr和unique_ptr。shared_ptr用于需要共享对象的时候,其删除器类型时运行时绑定的,只需reset时候传递给它一个可调用对象。(可调用对象包含,函数指针,lamda表达式,重载了调用运算符的类的对象)unique_ptr在编译时绑定,因此需要在创建时指定其类型。一般能使用静态对象就不动态创建,当需要管理对象的生存期时,首先考虑使用unique_ptr。如果多个类要共享成员那么使用shared_ptr。

std::shared_ptr<Circle> circle_ptr std::make_shared<Circle>(Circle(5));

std::unique_ptr<Circle> circle_ptr2{ new Circle(5)};

class Foo;

template<typename T>

std::shared_ptr<Foo> Factory(T arg)

{

return make_shared<Foo>(arg);

}

  1. 标准库move函数

获得绑定到左值的右值引用,左值位于等号的左边,右值位于等号右边。变量既是左值又是右值。常量表达式是右值。右值引用智能绑定到临时对象上,由此可知它所引用的对象将要被销毁,该对象没有其他用户。

int &&rr1 = 42;

int && rr3 = std::move(rr1);

  • lamda表达式

lamda是C++11的重头戏,lamda表达式是匿名类的匿名对象,可用作函数参数,可配合STL算法使用,可以用函数指针调用。Lamda表达式形如[捕获列表](函数参数)->返回值{函数体}

/*函数指针调用lamda*/

auto f = []{return 42; };

std::cout << f() << "\n";

/*配合STL算法使用*/

std::vector<std::string> words = {"helllo","world","c++11"};

std::stable_sort(words.begin(), words.end(),

[](const std::string& s1, const std::string& s2){return s1.size() < s2.size(); });

const std::size_t sz = 3;

auto wc = std::find_if(words.begin(), words.end(),

[sz](const std::string& s){return s.size()>=sz; });

std::for_each(words.begin(), words.end(), [](const std::string& s){std::cout << s<<" "; });

/*指定lamda返回类型*/

std::transform(stl_vector.begin(), stl_vector.end(), stl_vector.begin(),

[](int i)->int{if (i < 0) return -i; else return i; });

  • 标准库bind函数

bind可以理解为函数适配器,它接受一个可调用对象,生成一个新的可调用对象来适应原对象的参数列表。

/*-1是占位符,表示check6只有一个形参*/

auto check6 = std::bind(CheckSize, std::placeholders::_1, 6);

std::string s = { "hello" };

bool b1 = check6(s);

auto wc = std::find_if(words.begin(),words.end(),std::bind(CheckSize,std::placeholders::_1,sz));

  • 标准库的begin和end函数

    /*begin和end是STL的*/

    for (auto it = std::begin(stl_vector); it != std::end(stl_vector); ++it)

    {

    std::cout << *it << "\t";

    }

  1. 标准库initializer_list

为编写形参类型相同数量不同的函数

void ErrorMsg(std::initializer_list<std::string> il)

{

for (auto e : il)

{

std::cout << e << " ";

}

std::cout << std::endl;

}

ErrorMsg({ "funcionX", "okay" });

  • 标准库加入的容器array,forward_list,unordered_set,unordered_map

分别为定长数组,单链表,哈希表实现的set,哈希表实现的map。

namespace std

{

template<>

struct hash<SalesData>

{

typedef size_t result_type;

typedef SalesData argument_type;

size_t operator()(const SalesData& s) const;

};

/*自定义哈希函数*/

size_t hash<SalesData>::operator()(const SalesData& s) const

{

return hash<string>()(s.book_no) ^ hash<unsigned>()(s.units_sold) ^ hash<double>()(s.revenue);

}

}

std::unordered_multiset<SalesData> sales_data;

  • 默认模板参数

    template<typename T=int>

    std::shared_ptr<Foo> Factory(T arg)

    {

    return make_shared<Foo>(arg);

    }

  1. 可变参数模板

    /*可参数递归打印*/

    template<typename T>

    std::ostream& Print(std::ostream& os, const T& t)

    {

    return os << t;

    }

    template<typename T, typename...Args>

    std::ostream& Print(std::ostream& os, const Args&...rest)

    {

    os << t << ",";

    return Print(os, rest...);

    }

那些忘记的但却很有用的C++11特性

  • 列表初始化返回值

    std::vector<std::string> Process(const std::string& expected)

    {

    if (expected.empty())

    return{};

    else if (expected == "aucual")

    return{ "hello ", "world " };

    else

    return{ "bingo" };

    }

  • 委托构造函数

说白了就是构造函数调用构造函数。

class SalesData

{

public:

SalesData(std::string s, unsigned cnt, double price) :book_no{ s }, units_sold{ cnt }, revenue{ price }

{}

SalesData() :SalesData("", 0, 0){}

SalesData(std::string s) :SalesData(s, 0, 0){}

friend class std::hash<SalesData>;

private:

std::string book_no;

unsigned int units_sold;

double revenue;

};

  • 移动构造和移动赋值

    class Hasptr

    {

    public:

    /*复制构造*/

    Hasptr(const Hasptr& p) :ps{ p.ps }, i{ p.i }{}

    /*赋值操作符*/

    Hasptr& operator=(const Hasptr& p);

    /*移动构造*/

    Hasptr(Hasptr&& p) :ps{ p.ps }, i{ p.i }{ p.ps = 0; }

    /*移动赋值操作符*/

    Hasptr& operator=(Hasptr&& rhs)

    {

    std::swap(*this, rhs); return*this;

    }

    private:

    std::string * ps;

    int i;

    };

  • function类模板

std::function<int(int, int)> f1 = add;

std::function<int(int, int)> f2 = [](int i, int j){return i*j; };

  • 随机数库

    /*每次调用都生成不同随机数*/

    std::vector<unsigned> GenRand()

    {

    static std::default_random_engine e;

    static std::uniform_int_distribution<unsigned> u(0, 9);

    std::vector<unsigned> ret;

    for (size_t i = 0; i < 100; ++i)

    ret.push_back(u(e));

    return ret;

    }

/*实随机数*/

std::default_random_engine e;

std::uniform_real_distribution<double> u(0, 1);

for (size_t i = 0; i < 10; ++i)

std::cout << u(e) << "";

/*正太分布的随机数*/

std::normal_distribution<>n(4, 1.5);// 4 均值 1.5标准差

如何使用C++11

  • 微软编译器支持最全的是vs2013。
  • Clang几乎全部支持,Clang是一款开源编译器。
  • G++也支持的非常全面。

具体情况参考http://www.oschina.net/translate/c11-compiler-support-shootout-visual-studio-gcc-clang-intel

Wow C++11的更多相关文章

  1. 33个好用的图片轮显 jquery图片轮显

    原文发布时间为:2011-05-28 -- 来源于本人的百度文章 [由搬家工具导入] 我个人还是喜欢 jquery.recycle,比较通用。因为由美工设计好的轮显结构,如果套用下面,就感觉不是很方便 ...

  2. 地区sql

    /*Navicat MySQL Data Transfer Source Server : localhostSource Server Version : 50136Source Host : lo ...

  3. gitlab使用个人版v16.11

    title: gitlab使用个人版v16.11 date: 2016-11-13 20:53:00 tags: [gitlab] --- 1.安装gitbash 附上地址链接:git 2.配置git ...

  4. python第二天基础1-1

    一.作用域 对于变量的作用域,执行声明并在内存中存在,该变量就可以在下面的代码中使用. if 1==1: name = 'wupeiqi' print name 二.三元运算 result = 值1  ...

  5. C Primer Plus(第五版)11

    第 11 章 字符串和字符串函数 在本章中你将学习下列内容: · 函数: gets(), puts(), strcat(), strncat(), strcmp(), strncmp(), strcp ...

  6. C++ 11 笔记 (三) : auto

    我真的不是标题党... 虽然大一上学期学C语言基础时就学了auto关键字了,而且还是跟static和register两个关键字打包学的,但是.. 猜的没错,C++11这货又给auto加新功能了,在 C ...

  7. (转)iOS Wow体验 - 第一章 - iOS人机界面设计规范纵览

    本文是<iOS Wow Factor:Apps and UX Design Techniques for iPhone and iPad>第一章译文精选,其余章节将陆续放出. 关于本套译文 ...

  8. WOW

    WOW http://bbs.ngacn.cc/read.php?tid=4992959  http://ngasave.us/popcn/?t=gems  地精科技:国服最流行 http://bbs ...

  9. HDU-4850 Wow! Such String! (构造)

    Problem Description Recently, doge starts to get interested in a strange problem: whether there exis ...

随机推荐

  1. Chrome插件Axure RP Extension

    Chrome插件Axure RP Extension 1.将文件夹“0.6.2_0”复制到Chrome文件夹中某个位置. 2.打开Chrome,打开[设置] - [扩展程序],勾选右上角的“开发者模式 ...

  2. 简单来说一下java中的泛型,ssh中dao层使用会简化代码量

    原来仅仅是听老师说泛型特别好用,但是后来一直弄android用的泛型就比較少了.但是感觉它真的非常重要,于是花了一下午的时间写了个demo.好,老规矩.上代码: 首先,sysout是个工具,可是用着不 ...

  3. linux 下的两种软件安装方式 —— 源码(编译、安装),编译好的二进制(直接安装)

    我们以 GPG(加密工具)为例来说明两种安装方式的区别: 源码(Source code releases,名称中则会含有src等说明信息,tarball:source),先编译再安装 GPU 的源码地 ...

  4. (转载)Mac下使用Android Studio 获取 SHA1和MD5

    Mac下使用Android Studio 获取 SHA1和MD5 2015-08-10 15:38 1776人阅读 评论(1) 收藏 举报  分类: Android(14)  版权声明:本文为博主原创 ...

  5. hiho 1571 - 贪心好题*

    题目链接 小Hi在帮助钢铁侠开发新的盔甲.这套新盔甲一共包含M种武器插槽,其中第i种插槽有Ci个.每个插槽最多安装一个武器模块. 小Hi一共准备了N个武器模块,编号1~N.每个武器模块都有三个参数Vi ...

  6. HDU 1856 More is better【并查集】

    解题思路:将给出的男孩的关系合并后,另用一个数组a记录以find(i)为根节点的元素的个数,最后找出数组a的最大值 More is better Time Limit: 5000/1000 MS (J ...

  7. RocketMQ学习笔记(1)----RocketMQ的简介

    1. 什么是RocketMQ? 是一个队列模型的消息中间件,具有高性能.高可靠.高实时.分布式特点. Producer.Consumer.队列都可以分布式.  Producer 吐一些队列轮流収送消息 ...

  8. nginx 子进程 woker process 启动失败的问题

    问题: 重启nginx服务,worker process 子进程启动失败,启动的都是master进程: 负载急速升高(平常都是4-5),占用CPU资源多的前十进程都是nginx : nginx 错误日 ...

  9. C# AES 加解密处理

    引言 这是一个有关AES加解密的方法类 一.设置AES加解密密钥:下面列出自己分配的三类密钥 private const string UserKey = "roshan-2015-user ...

  10. WordPress 不错的插件

    Akismet – 防止垃圾评论 WP-PostViews Plus - 页面访问量统计 All in One SEO Pack – 搜索引擎优化的插件,自动优化搜索引擎. WP Super Cach ...