存档

文章标签 ‘c++’

C++11/14 新特性 (多线程)

2017/03/28 522

在 C++11 之前 ,C++ 标准并没有提供统一的并发编程标准,也没有提供语言级别的支持。这导致我们在编写可移植的多线程程序时很不方便,往往需要面向不同的平台进行不同的实现,或者引入一些第三方平台,如Boost,pthread_win32 等。 从C++11开始 ,对并发编程进行了语言级别的支持,使用使用C++进行并发编译方便了很多。这里介绍C++11并发编译的相关特性。

1 线程

1.1 线程的创建

std::thread 的构造函数如下:

我们只需要提供线程函数或函数对象,即可以创建线程,并可以同时指定线程函数的参数。

join函数将会阻塞线程,直到线程函数执行完毕,主线程才会接着执行。如果线程函数有返回值,返回值将被忽略。 在使用线程对象的过程中,我们需要注意线程对象的生命周期。如果线程对象先于线程函数结束,那么将会出现不可预料的错误。可以通过线程阻塞的方式来等待线程函数执行完(join),或让线程在后台执行。 如果不希望线程被阻塞,可以调用线程的 detach() 函数,将线程与线程对象分离。但需要注意的是,detach 之后的线程无法再使用join来进行阻塞了,即detach之后的线程,我们无法控制了。当我们不确定一个线程是否可以join时,可以先使用 thead::joinable() 来进行判断。

另外,我们还可以通过 std::bind, lambda 来创建线程(其实就是使用函数对象创建线程)。

线程不可以被复制,但是可以被移动:
阅读全文…

C++11/14 新特性(function/bind 可调用对象包装器与绑定器)

2017/02/28 509

1 可调用对象

在 C++ 中,可调用对象一般是指:

  • 一个函数指针
  • 一个重载 () 操作符的类对句(仿函数)
  • 一个可被转换为函数指针的类对象
  • 一个类成员函数指针

上例中的这些对象(func_ptr,foo,bar,mem_func_ptr,mem_obj_ptr) 均可称之为 “可调用对象”。相应的,其类型可被称作“可调用类型”。注意这里只有成员函数有成员函数指针而没有函数类型或函数引用类型,这是因为函数类型并不能直接用于定义对象,而函数引用或以看做一个 const 的函数指针。 可调用对象具有比较统一的调用形式,即使用括号操作(除成员函数指针),而定义的方法各不一样。这样我们在试图使用统一的方式保存,或传递一个可调用对象时,会十分烦琐。

2 std::function 可调用对象包装器

std::function 是一个类模板,它可以容纳除了类成员(函数)指针之外的所有可调用对象。通过指定它的模板参数,它可以用统一的方式处理函数、函数对象、函数指针,并允许保存和延迟调用它们。
阅读全文…

C++11/14 新特性 (使用 chrono 进行时间处理)

2017/01/03 498

在c++11以前,我们获取当前时间的时间戳,需要借助于第三方库,如 boost ,或者针对不同的操作做不同的处理:

而在c++11中,这个问题得到解决。 c++11 标准库中提供 chrono库,用来处理时间相关的数据。

1 duration 记录时长

duration 表示一段时间间隔。其原型:


_Rep 为一个数值类型,如 int, long, 用来表示时钟数的类型。 _Period 为一个默认的模板参数 std::ratio,表示时钟周期。 ratio的原型:

它表示一个时钟周期的秒数。_Num 代表分子,_Den代表分母,它们的比值就是一个时钟周期,可以通过调整分子与分母来表示任意一个时钟周期。如 ratio<1> 表示一个时钟周期为1秒,ratio<3600>表示一个时钟周期为1小时,ratio<1,1000>表示一个时钟周期为1毫秒,ratio<1,2>表示一个时钟周期为0.2秒,ratio<9/7>表示一个时钟周期为9/7秒。 标准库将一些常用的时钟周期做了定义:

在不同的时钟周期中,我们可以使用 chrono_cast 来进行转换。两个 duration还可以进行加减运算:

阅读全文…

C++11/14 新特性(类型/初始化/智能指针)

2016/12/01 478

数据类型cpplogo

1.long long

long long 数据类型,提供至少 64 位的整型数据。

2.nullptr

C++11 推荐使用 nullptr 表示空指针,不再推荐使用 NULL 或 0 表示空指针。 NULL为从 C 语言中引进的,在 C 语言中一般被定义为宏:

在 C 语言中,可以将 void* 隐式转换为任意指针类型,而在 C++ 中,可以为任意类型的指针赋 0 值。所以 c++ 将 NULL 定义为 0. nullptr 是指针类型(nullptr_t),该类型的对象不允许转换到非指针类型。

3.contexpr

1).const expression  常量表达式

是指值不会改变且在编译过程中就能得到计算结果的表达式。字面量属于常量表达式,使用常量表达式初始化的 const 对象也是常量表达式。一个对象或表达式是不是常量表达式要由它的数据类型和初始值共同决定:

尽管 size 变量的初始化值是字面常量 ,但是它的定义数据类型是 int 而不是 const int 。 尽管 sz 定义为 const int ,但其值需要运行时才能得到,所以它也不是常量表达式。

2).constexpr 变量

C++11 中,允许将变量声明为 constexpr 类型,以便由编译器检查变量是否为一个常量表达式:声明为 constexpr 的变量一定是一个常量 ,且必须使用常量表达式初始化:

3).constexpr 函数

constexpr 可用于指示函数是一个常量表达式。这需要满足:

  • 返回值类型是字面值类型
  • 形参类型是字面值类型
  • 函数体中必须有且仅有一条 return 语句

4).constexpr 与 const

这里的 p 和 q 本质是不一样的。指针 p 指向的整数是常量,而指针 q 本身是常量,其指向的整数则可以不是常量:

其中的关键在于constexpr把它所定义的对象置为了顶层const.

4.noexcept

noexcept 指示一个函数不会抛出异常。如果一个使用 noexcept 修饰的函数内部抛出了异常,编译器并不会报错,但

阅读全文…