鍍金池/ 教程/ C/ A.2 刪除函數(shù)
3.4 本章總結(jié)
6.3 基于鎖設(shè)計(jì)更加復(fù)雜的數(shù)據(jù)結(jié)構(gòu)
6.1 為并發(fā)設(shè)計(jì)的意義何在?
5.2 <code>C++</code>中的原子操作和原子類型
A.7 自動(dòng)推導(dǎo)變量類型
2.1 線程管理的基礎(chǔ)
8.5 在實(shí)踐中設(shè)計(jì)并發(fā)代碼
2.4 運(yùn)行時(shí)決定線程數(shù)量
2.2 向線程函數(shù)傳遞參數(shù)
第4章 同步并發(fā)操作
2.3 轉(zhuǎn)移線程所有權(quán)
8.3 為多線程性能設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)
6.4 本章總結(jié)
7.3 對(duì)于設(shè)計(jì)無鎖數(shù)據(jù)結(jié)構(gòu)的指導(dǎo)建議
關(guān)于這本書
A.1 右值引用
2.6 本章總結(jié)
D.2 &lt;condition_variable&gt;頭文件
A.6 變參模板
6.2 基于鎖的并發(fā)數(shù)據(jù)結(jié)構(gòu)
4.5 本章總結(jié)
A.9 本章總結(jié)
前言
第10章 多線程程序的測(cè)試和調(diào)試
5.4 本章總結(jié)
第9章 高級(jí)線程管理
5.1 內(nèi)存模型基礎(chǔ)
2.5 識(shí)別線程
第1章 你好,C++的并發(fā)世界!
1.2 為什么使用并發(fā)?
A.5 Lambda函數(shù)
第2章 線程管理
4.3 限定等待時(shí)間
D.3 &lt;atomic&gt;頭文件
10.2 定位并發(fā)錯(cuò)誤的技術(shù)
附錄B 并發(fā)庫(kù)的簡(jiǎn)單比較
5.3 同步操作和強(qiáng)制排序
A.8 線程本地變量
第8章 并發(fā)代碼設(shè)計(jì)
3.3 保護(hù)共享數(shù)據(jù)的替代設(shè)施
附錄D C++線程庫(kù)參考
第7章 無鎖并發(fā)數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)
D.7 &lt;thread&gt;頭文件
D.1 &lt;chrono&gt;頭文件
4.1 等待一個(gè)事件或其他條件
A.3 默認(rèn)函數(shù)
附錄A 對(duì)<code>C++</code>11語言特性的簡(jiǎn)要介紹
第6章 基于鎖的并發(fā)數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)
封面圖片介紹
7.2 無鎖數(shù)據(jù)結(jié)構(gòu)的例子
8.6 本章總結(jié)
8.1 線程間劃分工作的技術(shù)
4.2 使用期望等待一次性事件
8.4 設(shè)計(jì)并發(fā)代碼的注意事項(xiàng)
D.5 &lt;mutex&gt;頭文件
3.1 共享數(shù)據(jù)帶來的問題
資源
9.3 本章總結(jié)
10.3 本章總結(jié)
10.1 與并發(fā)相關(guān)的錯(cuò)誤類型
D.4 &lt;future&gt;頭文件
3.2 使用互斥量保護(hù)共享數(shù)據(jù)
9.1 線程池
1.1 何謂并發(fā)
9.2 中斷線程
4.4 使用同步操作簡(jiǎn)化代碼
A.2 刪除函數(shù)
1.3 C++中的并發(fā)和多線程
1.4 開始入門
第5章 C++內(nèi)存模型和原子類型操作
消息傳遞框架與完整的ATM示例
8.2 影響并發(fā)代碼性能的因素
7.1 定義和意義
D.6 &lt;ratio&gt;頭文件
A.4 常量表達(dá)式函數(shù)
7.4 本章總結(jié)
1.5 本章總結(jié)
第3章 線程間共享數(shù)據(jù)

A.2 刪除函數(shù)

有時(shí)讓類去做拷貝是沒有意義的。std::mutex就是一個(gè)例子——拷貝一個(gè)互斥量,意義何在?std::unique_lock<>是另一個(gè)例子——一個(gè)實(shí)例只能擁有一個(gè)鎖;如果要復(fù)制,拷貝的那個(gè)實(shí)例也能獲取相同的鎖,這樣std::unique_lock<>就沒有存在的意義了。實(shí)例中轉(zhuǎn)移所有權(quán)(A.1.2節(jié))是有意義的,其并不是使用的拷貝。當(dāng)然其他例子就不一一列舉了。

通常為了避免進(jìn)行拷貝操作,會(huì)將拷貝構(gòu)造函數(shù)和拷貝賦值操作符聲明為私有成員,并且不進(jìn)行實(shí)現(xiàn)。如果對(duì)實(shí)例進(jìn)行拷貝,將會(huì)引起編譯錯(cuò)誤;如果有其他成員函數(shù)或友元函數(shù)想要拷貝一個(gè)實(shí)例,那將會(huì)引起鏈接錯(cuò)誤(因?yàn)槿鄙賹?shí)現(xiàn)):

class no_copies
{
public:
  no_copies(){}
private:
  no_copies(no_copies const&);  // 無實(shí)現(xiàn)
  no_copies& operator=(no_copies const&);  // 無實(shí)現(xiàn)
};

no_copies a;
no_copies b(a);  // 編譯錯(cuò)誤

在C++11中,委員會(huì)意識(shí)到這種情況,但是沒有意識(shí)到其會(huì)帶來攻擊性。因此,委員會(huì)提供了更多的通用機(jī)制:可以通過添加= delete將一個(gè)函數(shù)聲明為刪除函數(shù)。

no_copise類就可以寫為:

class no_copies
{
public:
  no_copies(){}
  no_copies(no_copies const&) = delete;
  no_copies& operator=(no_copies const&) = delete;
};

這樣的描述要比之前的代碼更加清晰。也允許編譯器提供更多的錯(cuò)誤信息描述,當(dāng)成員函數(shù)想要執(zhí)行拷貝操作的時(shí)候,可將連接錯(cuò)誤轉(zhuǎn)移到編譯時(shí)。

拷貝構(gòu)造和拷貝賦值操作刪除后,需要顯式寫一個(gè)移動(dòng)構(gòu)造函數(shù)和移動(dòng)賦值操作符,與std::threadstd::unique_lock<>一樣,你的類是只移動(dòng)的。

下面清單中的例子,就展示了一個(gè)只移動(dòng)的類。

清單A.2 只移動(dòng)類

class move_only
{
  std::unique_ptr<my_class> data;
public:
  move_only(const move_only&) = delete;
  move_only(move_only&& other):
    data(std::move(other.data))
  {}
  move_only& operator=(const move_only&) = delete;
  move_only& operator=(move_only&& other)
  {
    data=std::move(other.data);
    return *this;
  }
};

move_only m1;
move_only m2(m1);  // 錯(cuò)誤,拷貝構(gòu)造聲明為“已刪除”
move_only m3(std::move(m1));  // OK,找到移動(dòng)構(gòu)造函數(shù)

只移動(dòng)對(duì)象可以作為函數(shù)的參數(shù)進(jìn)行傳遞,并且從函數(shù)中返回,不過當(dāng)想要移動(dòng)左值,通常需要顯式的使用std::move()static_cast<T&&>。

可以為任意函數(shù)添加= delete說明符,添加后就說明這些函數(shù)是不能使用的。當(dāng)然,還可以用于很多的地方;刪除函數(shù)可以以正常的方式參與重載解析,并且如果被使用只會(huì)引起編譯錯(cuò)誤。這種方式可以用來刪除特定的重載。比如,當(dāng)函數(shù)以short作為參數(shù),為了避免擴(kuò)展為int類型,可以寫出重載函數(shù)(以int為參數(shù))的聲明,然后添加刪除說明符:

void foo(short);
void foo(int) = delete;

現(xiàn)在,任何向foo函數(shù)傳遞int類型參數(shù)都會(huì)產(chǎn)生一個(gè)編譯錯(cuò)誤,不過調(diào)用者可以顯式的將其他類型轉(zhuǎn)化為short:

foo(42);  // 錯(cuò)誤,int重載聲明已經(jīng)刪除
foo((short)42);  // OK
上一篇:前言下一篇:1.1 何謂并發(fā)