1 using用法
1)配合命名空间,对命名空间权限进行管理
using namespace std;//释放整个命名空间到当前作用域 using std::cout; //释放某个变量到当前作用域
2)类型重命名
作用等同typedef,但是逻辑上更直观。
#include <iostream> using namespace std; #define DString std::string //! 不建议使用! typedef std::string TString; //! 使用typedef的方式 using Ustring = std::string; //!使用 using typeName_self = stdtypename; //更直观 typedef void (tFunc*)(void); using uFunc = void(*)(void); int main(int argc, char *argv[]) { TString ts("String!"); Ustring us("Ustring!"); string s("sdfdfsd"); cout<<ts<<endl; cout<<us<<endl; cout<<s<<endl; return 0; }
3)继承体系中,改变部分接口的继承权限。
有这样一种应用场景,比如我们需要私有继承一个基类,然后又想将基类中的某些public接口在子类对象实例化后对外开放直接使用。如下即可
#include <iostream> //#include <array> #include <typeinfo> using namespace std; class Base { public: Base() {} ~Base(){} void dis1() { cout<<"dis1"<<endl; } void dis2() { cout<<"dis2"<<endl; } }; class BaseA:private Base { public: using Base::dis1;//需要在BaseA的public下释放才能对外使用, void dis2show() { this->dis2(); } }; int main(int argc, char *argv[]) { BaseA ba; ba.dis1(); ba.dis2show(); return 0; }
2 enable_shared_from_this
通常我们不能直接返回this指针,若函数将 this 指针返回到外部某个变量保存,若该对象自身已经析构了,但外部变量并不知道,此时外部变量再使用这个指针,就会使得程序崩溃。
若类 T 继承 std::enable_shared_from_this ,则会为该类 T 提供成员函数shared_from_this 。 当 T 类型对象 t 被一个为名为 pt 的 std::shared_ptr 类对象管理时,调用 T::shared_from_this 成员函数,将会返回一个新的 std::shared_ptr 对象,它与 pt 共享 t 的所有权。
3 dynamic_pointer_cast
shared_ptr<CDerive> spDeriveUp= make_shared<CDerive>(); shared_ptr<CBase> spBaseUp; //智能指针上行转换 spBaseUp = dynamic_pointer_cast<CBase>(spDeriveUp); //智能指针下行转换 pDeriveDown = dynamic_pointer_cast<CDerive>(spBaseDown); if (spDeriveDown == NULL) //由于会进行类型的检查,这边是返回NULL cout << "spDeriveDown is null" << endl;
4 std::mutex
构造函数,std::mutex不允许拷贝构造,也不允许 move 拷贝,最初产生的 mutex 对象是处于 unlocked 状态的。
lock(),调用线程将锁住该互斥量。线程调用该函数会发生下面 3 种情况:
(1). 如果该互斥量当前没有被锁住,则调用线程将该互斥量锁住,直到调用 unlock之前,该线程一直拥有该锁。
(2). 如果当前互斥量被其他线程锁住,则当前的调用线程被阻塞住。
(3). 如果当前互斥量被当前调用线程锁住,则会产生死锁(deadlock)。
unlock(), 解锁,释放对互斥量的所有权。
try_lock(),尝试锁住互斥量,线程调用该函数也会出现下面 3 种情况:
(1). 如果当前互斥量没有被其他线程占有,则该线程锁住互斥量,直到该线程调用 unlock 释放互斥量。
(2). 如果当前互斥量被其他线程锁住,则当前调用线程返回 false,而并不会被阻塞掉。
(3). 如果当前互斥量被当前调用线程锁住,则会产生死锁(deadlock)。
std::recursive_mutex
std::recursive_mutex 与 std::mutex 一样,也是一种可以被上锁的对象,但是和 std::mutex 不同的是,std::recursive_mutex 允许同一个线程对互斥量多次上锁(即递归上锁),来获得对互斥量对象的多层所有权,std::recursive_mutex 释放互斥量时需要调用与该锁层次深度相同次数的 unlock(),可理解为 lock() 次数和 unlock() 次数相同,除此之外,std::recursive_mutex 的特性和 std::mutex 大致相同。
例如函数a需要获取锁mutex,函数b也需要获取锁mutex,同时函数a中还会调用函数b。如果使用std::mutex必然会造成死锁。但是使用std::recursive_mutex就可以解决这个问题。
std::time_mutex
std::time_mutex 比 std::mutex 多了两个成员函数,try_lock_for(),try_lock_until()。
try_lock_for 函数接受一个时间范围,表示在这一段时间范围之内线程如果没有获得锁则被阻塞住(与 std::mutex 的 try_lock() 不同,try_lock 如果被调用时没有获得锁则直接返回 false),如果在此期间其他线程释放了锁,则该线程可以获得对互斥量的锁,如果超时(即在指定时间内还是没有获得锁),则返回 false。
try_lock_until 函数则接受一个时间点作为参数,在指定时间点未到来之前线程如果没有获得锁则被阻塞住,如果在此期间其他线程释放了锁,则该线程可以获得对互斥量的锁,如果超时(即在指定时间内还是没有获得锁),则返回 false。