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的实例。参考定义:

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能。

转载于:https://my.oschina.net/zbchmain/blog/699661

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值