Wow C++11
什么是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++11 FAQ http://www.stroustrup.com/C++11FAQ.html
- 买第五版的《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;
- 类中的变量初始化
/*类内初始化,内置类型和自定义类型*/
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);
}
- 标准库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";
}
- 标准库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);
}
- 可变参数模板
/*可参数递归打印*/
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的更多相关文章
- 33个好用的图片轮显 jquery图片轮显
原文发布时间为:2011-05-28 -- 来源于本人的百度文章 [由搬家工具导入] 我个人还是喜欢 jquery.recycle,比较通用。因为由美工设计好的轮显结构,如果套用下面,就感觉不是很方便 ...
- 地区sql
/*Navicat MySQL Data Transfer Source Server : localhostSource Server Version : 50136Source Host : lo ...
- gitlab使用个人版v16.11
title: gitlab使用个人版v16.11 date: 2016-11-13 20:53:00 tags: [gitlab] --- 1.安装gitbash 附上地址链接:git 2.配置git ...
- python第二天基础1-1
一.作用域 对于变量的作用域,执行声明并在内存中存在,该变量就可以在下面的代码中使用. if 1==1: name = 'wupeiqi' print name 二.三元运算 result = 值1 ...
- C Primer Plus(第五版)11
第 11 章 字符串和字符串函数 在本章中你将学习下列内容: · 函数: gets(), puts(), strcat(), strncat(), strcmp(), strncmp(), strcp ...
- C++ 11 笔记 (三) : auto
我真的不是标题党... 虽然大一上学期学C语言基础时就学了auto关键字了,而且还是跟static和register两个关键字打包学的,但是.. 猜的没错,C++11这货又给auto加新功能了,在 C ...
- (转)iOS Wow体验 - 第一章 - iOS人机界面设计规范纵览
本文是<iOS Wow Factor:Apps and UX Design Techniques for iPhone and iPad>第一章译文精选,其余章节将陆续放出. 关于本套译文 ...
- WOW
WOW http://bbs.ngacn.cc/read.php?tid=4992959 http://ngasave.us/popcn/?t=gems 地精科技:国服最流行 http://bbs ...
- HDU-4850 Wow! Such String! (构造)
Problem Description Recently, doge starts to get interested in a strange problem: whether there exis ...
随机推荐
- hdu 2032 一维数组实现杨辉三角
杨辉三角 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- 朝花夕拾——finally/final/finalize拨云雾见青天
Java编程中.常常会使用到异常处理,而finally看似的是try/catch后对逻辑处理的完好,事实上里面却存在非常多隐晦的陷阱.final常见于变量修饰,那么你在内部类中也见过吧.finaliz ...
- nyoj--914--Yougth的最大化(二分查找)
Yougth的最大化 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 Yougth现在有n个物品的重量和价值分别是Wi和Vi,你能帮他从中选出k个物品使得单位重量的价值最 ...
- 安装Oracle RAC 11g
1.Oracle Enterprise Linux 和 iSCSI 上构建 Oracle RAC 11g 集群 2.Oracle RAC 的所有共享磁盘存储将基于 iSCSI,iSCSI 使用在第三个 ...
- c:\Windows\System32\drivers\etc\hosts的作用
c:\Windows\System32\drivers\etc\hosts 是域名解析文件. 可以直接用记事本打开.将IP地址重定向. 格式为:ip地址-空格-域名 可以将一个域名重新定向到一个IP ...
- correct ways to define variables in python
http://stackoverflow.com/questions/9056957/correct-way-to-define-class-variables-in-python later say ...
- python中各项目文件含义(新手可看)
其他不用多说,这里主要阐述三个概念,包.模块.类 包我们可以看作一个包含__init__.py 和一系列.py 文件的文件夹,包含__init__.py这样做的目的是为了区别包和普通字符串,读者可以试 ...
- 18.boost 图的拓扑排序
运行结果: 代码示例: #include <iostream> #include <vector> #include <deque> #include <bo ...
- swift语言点评十九-类型转化与检查
1.oc比较: -(BOOL) isKindOfClass: classObj判断是否是这个类或者这个类的子类的实例 -(BOOL) isMemberOfClass: classObj 判断是否是这个 ...
- SpringBoot学习笔记(9)----SpringBoot中使用关系型数据库以及事务处理
在实际的运用开发中,跟数据库之间的交互是必不可少的,SpringBoot也提供了两种跟数据库交互的方式. 1. 使用JdbcTemplate 在SpringBoot中提供了JdbcTemplate模板 ...