您的位置:首页 > 编程语言 > C语言/C++

c++11学习笔记

2016-06-23 00:00 489 查看
摘要: c++11学习笔记;日积月累。

1. <chrono>库

1)3个概念:

a. 时间段(Durations)

代表一个时间段。使用模板类duration表示。duration模板有两个参数:时间量(count representation)、时间单位(period precision)。例如,10ms的时间量为10,时间单位为毫秒。

b. 时间点(Time points)

代表一个时间点。使用类模板time_point表示。它使用从时钟起始时间(epoch,如Unix时间戳1970-01-01 00:00:00 UTC)计的时间段表示。它是一个固定的值,在不同的时钟上代表不同的时间。

c. 时钟(Clocks)

它是一个解释时间点的机制。有一个时间起点(epoch),时间点就是从该时间起点计的时间段。库中提供了至少3种时钟,分别是system_clock、steady_clock、high_resolution_clock。

时间点和时钟相互依赖,共同表示一个确定的时间。

2)常用预定义类型

名字含义
hours
minutes
seconds
milliseconds毫秒
microseconds微秒
nanoseconds纳秒
示例:

#include<chrono>

// 10秒
std::chrono::seconds(10);

3)ratio

template <intmax_t N, intmax_t D = 1> class ratio;

模板实例表示一个分数形式的有理数,分子、分母是intmax_t类型。模板实例自身代表这个有理数,而不是模板实例的对象。模板实例只能被用做常量。

实例化后的模板像下面的样子:

// 1 / 3
struct ratio
{
static const intmax_t num = 1;
static const intmax_t den = 3;
};

4) duration

template <class Rep, class Period = ratio<1> >
class duration;

代表一个时间段。第一个参数为时间量的类型,第二个参数为时间单位的类型。时间量可以用count成员方法获取。时间单位是秒的比率。如

milliseconds ratio<1, 1000> // 1/1000秒

5)time_point

template <class Clock, class Duration = typename Clock::duration>
class time_point;

表示一个时间点。用以时钟的起始时间(epoch)计的一个时间段表示。使用成员函数time_from_epoch获取。

6)system_clock

获取当前时间的时钟。使用now成员函数返回当前时间。返回时间值得常用方法为:

std::chrono::system_clock::now().time_since_epoch().count();

参考:http://www.cplusplus.com/reference/chrono/

2. <random>库

1)mt19937

32位伪随机数生成器。是mersenne_twister_engine的实例。参考定义:

3ff0
typedef mersenne_twister_engine<
uint_fast32_t,
32,
624,
397,
31,
0x9908b0df,
11,
0xffffffff,
7,
0x9d2c5680,
15,
0xefc60000,
18,
1812433253>
mt19937;

// example
// 已当前时间为随机种子创建生成器
#include <chrono>
#include <random>
#include <iostream>

std::mt19937 generator(std::chrono::system_clock::now().time_since_epoch().count());
std::cout << generator() << std::endl;

参考:http://www.cplusplus.com/reference/random/

3. <mutex>库

1)lock_guard

管理一个mutex,在对象创建时锁定mutex,在对象销毁时解锁mutex。是一个方便的作用域锁。

2)unique_lock

管理一个mutex,在对象创建时锁定mutex,在对象销毁时解锁mutex。

3)lock_guard、unique_lock对比

a. lock_guard只有一个构造函数和析构函数,不能复制,不能赋值,没有提供其他接口。仅为mutex在一个作用域中的加锁和解锁提供了方便。

b. unique_lock提供了更多的接口。它最简单的用法和lock_guard一样。它可以复制、赋值,交换(swap),而且像是mutex的代理(proxy)。

c. 二者都不会控制mutex的生命周期,所以需要保证mutex的生命周期覆盖二者的生命周期。

4. <thread>库

1)thread

创建一个线程。

a. join

等待线程结束。会阻塞调用此函数的线程。

2)this_thread

代表当前线程。

#include <thread>
#include <iostream>

void ThreadRoutine(){
int count = 1000000;
float base = 1000;
float factor = 0.99F;

// 执行100万次浮点数运算
for(int i = 0; i < count; i++){
base *= factor;
}

std::cout << "thread " << std::this_thread::get_id() << std::endl;  // 打印当前线程的ID
}

int main(int argc, _TCHAR* argv[]){
std::thread thread0(ThreadRoutine, 0);
thread0.join();

std::thread thread1(ThreadRoutine, 1);
thread1.join();

std::thread thread2(ThreadRoutine, 2);
thread2.join();

std::cout << "thread main" << std::endl;  // 等待所有线程结束

return 0;
}


5. <utility>库

1)move

template <class T>
typename remove_reference<T>::type&& move (T&& arg) noexcept;

a. 右值(rvalue)

临时存储的表达式结果,如常量,函数返回值,构造函数调用。

b. 左值(lvalue)

一个相对持久的内存地址。可以用来存储右值。

class A{
public:
A(){}
};

int FnReturnValue(){
// 这里的lvalue也是个左值!函数的返回结果是个右值
int lvalue = 1;
return lvalue;
}

int main(){
// 函数调用产生一个右值,存储在栈上,如果没有左值接收,调用结束后在清理栈的时候会清除掉
FnReturnValue();

// lvalue是个左值,用来接收函数调用返回的右值
int lvalue = FnReturnValue();

// 产生右值,是A的对象,没有左值接收,立即析构
A();

// 产生右值,字符串字面值,没有左值接收,丢弃
"hello, world!";

return 0;
}

返回参数arg的右值引用(rvalue reference)。move强制转移值的语义(move semantics),即使值是个左值。示例:

#include <utility>
#include <vector>
#include <algorithm>
#include <iostream>

class A{
public:
A() : id(base++){
std::cout << "A(): " << id << std::endl;
}

A(const A& right) : id(base++){
std::cout << "A(const A&): " << id << " from " << right.id << std::endl;
}

// move constructor
// 如果有此定义,move会调用它,否则会调用copy constructor
A(A&& right) : id(base++){
std::cout << "A(A&&): " << id << " from " << right.id << std::endl;
}

~A(){
std::cout << "~A(): " << id << std::endl;
}

private:
int id;
static int base;
};

int A::base = 0;

int main(int argc, _TCHAR* argv[]){
typedef std::vector<A> VectA;
VectA objs;

std::cout << "push a0" << std::endl;
A a0;
objs.push_back(a0);			// 复制一次

std::cout << "push a1" << std::endl;
A a1;
objs.push_back(std::move(a1));		// 移动或复制

std::cout << "push a2" << std::endl;
objs.push_back(A());		        // 复制一次

std::cout << "after this" << std::endl;

return 0;
}


6. <memory>库

1)unique_ptr、shared_ptr

unique_ptr不能存入容器中,因为它不能拷贝、赋值。shared_ptr能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息