第6章 C++语言新特性111417专题二

发布时间 2023-03-24 15:02:45作者: sha_ckle

C++11:STL hashmap

Std::unordered_set的数据存储结构也是采用哈希表的方式结构操作,除此之外,std::unordered_set在插入时不会自动排序。

#include<iostream>
#include<string>
#include<set>
#include<unordered_set>

int main()
{
    std::unordered_set<int> un_set;
    
    un_set.insert(34);
    un_set.insert(25);
    un_set.insert(38);
    un_set.insert(26);
    un_set.insert(19);
    un_set.insert(29);
    un_set.insert(54);
    
    std::cout << "\nunordered_set:" << std::endl;
    for(auto it:un_set)
    {
        std::cout << it << std::endl;
    }
    
    std::set<int> st;
    st.insert(34);
    st.insert(25);
    st.insert(38);
    st.insert(26);
    st.insert(19);
    st.insert(29);
    st.insert(54);
    
    std::cout << "\nset:" << std::endl;
    for(auto it:st)
    {
        std::cout << it << std::endl;
    }
    
    return 0;
}

关联容器:unordered_map

unordered_map为一个关联容器,内部采用Hash表结构,具备快速检索的功能。特性:关联性、无序性、map、唯一性。

#include<iosteam>
#include<string>
#include<unordered_map>
using namespace std;

typedef unordered_map<string, string> strmap;

strmap merge(strmap str1, strmap str2)
{
    strmap temp(str1);
    temp.insert(str2,begin(), str2.end());
    return temp;
}

int main()
{
    strmap s1;
	strmap s2({ {"apple","red"},{"lemon","yellow"} }); // 使用数组初始化
	strmap s3({ {"orange","orange"},{"strawberry","red"} }); // 使用数组初始化

	strmap s4(s2); // 复制初始化
	strmap s5(merge(s3, s4)); // 移动初始化操作
	strmap s6(s5.begin(), s5.end()); // 范围初始化操作

	cout << "\n输出s6容器:\n";
	for (auto& x : s6)
		cout << " " << x.first << ":" << x.second;
	cout << endl;

	return 0;
}

function函数对象

C++函数对象:函数对象指定义operator()的对象,语法形式如下:

class FunctionObjectType

{

public:

​ void operator()(){

​ 操作语句}

};

优势:比普通函数要灵活(可以拥有状态),执行速度比函数指针要快。

我们以函数对象作为排序原则操作,具体如下:

#include<iostream>
#include<set>
using namespace std;

class TestA
{
public:
    TestA(string lname, string fname):_fname(fname),_lname(lname)
    {
		cout << "\n执行TestA类的构造函数" << endl;
    }
    string firstname()const
    {
        return _fname;
    }
    string lastname()const
    {
        return _lname;
    }
private:
    string _fname = nullptr;
    sting _lname = nullptr;
};

class TestB
{
public:
	bool operator()(const TestA& t1, const TestA& t2)const
    {
        return t1.lastname() < t2.lastname() || t1.lastname() == t2.lastname && t1.firstname() < t2.firstname();
    }
};

int main()
{
    set<TestA, TestB> sett;
    
    TestA t1("liu","san");
    TestA t2("xiao","ming");
    TestA t3("zhang","san");
    TestA t4("wang","xiao");
    
    sett.insert(t1);
    sett.insert(t2);
    sett.insert(t3);
    sett.insert(t4);
    
    fot(auto i : sett)
    {
        cout << i.lastname() << "," << i.firstname() << endl;
    }
    
    return 0;
    
}

atomic_flag/atomic应用

std::atomic_flag为原子布尔类型。它不同于所有std::atomic的特化,它保证是免锁。std::atomic<bool>,std::stomic_flag不提供加载或存储操作。

#include<iostream>
#include<atomic>

std::atomic_flag lock = ATOMTC_FLAG_INIT;//ATOMTC_FLAG_INIT——>定义能以语句用于初始化操作,清除状态的初始化
void FuncAt(int args)
{
    for(int i = 0; i < 10; i++)
    {
        while(lock.test_and_set(std::memory_order_acquire));//获得锁
        std::cout << "Output Threads:" << i << std::endl;
        lock.clear(std::memory_order_release);          
    }
}

int main()
{
    std::vector<std::thread> vct;
    for(int i = 0; i < 10; i++)
    {
        vct.emplace_back(FuncAt, i);
    }
    for(auto& t: vct)
    {
        t.join();
    }
    
    return 0;
}

条件变量:condition_variable

C++11标准中,使用条件变量condition_variable实现多线程间的同步操作:当条件不满足时,相关线程被一直阻塞,直到某种条件出现,这些线程才会被唤醒。

#include<iostream>
#include<thread>
#include<condition_variable>
#include<mutex>

std::mutex mx;
std::condition_variable scv;
bool ready = false;

void PrintID(int id)
{
    std::unique_lock <std::mutex> lock(mx);
    
    while(!ready)
    {
        scv.wait(lock);//当前线程被阻塞,当全局标志位变为true之后,才唤醒
    }
    std::cout << "Threads:" << id << std::endl;
}

void RunFunc()
{
    std::unique_lock <std::mutex> lock(mx);
    
    ready = true;//设置全局标志位true
    scv.notify_all();//唤醒所有线程
}

int main()
{
    std::thread thrs[5];
    
    for(int i = 0; i < 5; i++)
        thrs[i] = std::thread(Print ID , i);
    
    std::cout << "5 threads ready to race......\n";
    RunFunc();
    
    for(auto &t:thrs)
        t.join();
    
    return 0;
}

异常处理:exception(头文件stdexcept)

C++语言标准库当中有一些类代表异常,这些类都是从exception类派生出来的,比如:bad_typeid/bad_cast/bad_alloc/ios_base::failure等,它们都是从exception类派生类。

#include<iostram>
#include<stdexcept>
using namespace std;

class TestA
{
    virtual void Func(){
        
    }
};

class TestB:public TestA
{
public:
    void disp(){
        cout << "TESTB OK" << endl;
    }
};

void dispObject(TestA& t)
{
    try
    {
        TestB& tb = dynamic_cast<TestB&>(t);
        //在此转换若不安全,会抛出bad_cast异常
        tb.disp();
    }
    catch(bad_cast& e)
    {
        cerr << e.what() << endl;
    }
}

int main()
{
    TestB objb;
    dispObject(objb);
    
    return 0;
}

std::thread 多线程

#include<iostream>
#include<thread>
using namespace std;

void ThreadFunc1()
{
    cout << "ThreadFunc1()--A" << endl;
    this_thread::sleep_for(std::chrono::seconds(2));
    cout << "ThreadFunc2()--B" << endl;   
}

void ThreadFunc2(int args, string sp)
{
    cout << "ThreadFunc1()--A" << endl;
    this_thread::sleep_for(std::chrono::seconds(7));
    cout << "ThreadFunc2()--B" << endl;   
}

int main()
{
    thread ths1(ThreadFunc1);
    thread ths1(ThreadFunc2,10,"LS");
    
    ths1.join();
    cout << "join" << endl;
    ths2.detach();
    cout << "detach" << endl;
    
    return 0;
}