本節將舉例說明使用中的入侵容器。 並花點時間討論 作業。本指南的後續章節會進一步說明 以及其他一些概念 本節將針對 示範:
- 指標類型,以及用來控制物件的生命週期
- 包含「mix-ins」以及如何讓物件存在於物件中 都會在 Docker 容器中執行
- 如何對
fbl::
幹擾容器中的元素進行疊代器。 - 如何從
fbl::
侵入式容器中移除元素。 - 從
fbl::
侵入式容器設定建構依附元件。
簡易範例
讓我們從簡單的範例開始著手。在這個範例中
會定義列於連結不連貫的名單中,並使用
std::unique_ptr<>
。這些物件的清單如下:
- 已填入
- 疊代以顯示物件的子集
- 疊代以移除物件的子集
- 已明確清理
#include <stdint.h>
#include <fbl/intrusive_double_list.h>
// An object that holds an immutable int and can exist on a doubly linked list
// managed using a std::unique_ptr
class MyObject : public fbl::DoublyLinkedListable<std::unique_ptr<MyObject>> {
public:
explicit MyObject(int val) : val_(val) {}
int val() const { return val_; }
private:
const int val_;
};
extern void TakeThisObjectFromMe(std::unique_ptr<MyObject>);
void DoThings() {
fbl::DoublyLinkedList<std::unique_ptr<MyObject>> list;
// Add 100 random integers to our list.
for (uint32_t i = 0; i < 100; ++i) {
list.push_back(std::make_unique<MyObject>(rand()));
}
// print out any members of the list that are even
for (const auto& obj : list) {
if (!(obj.val() % 2)) {
printf("Even Object %d\n", obj.val());
}
}
// Remove any objects that are divisible by 7 and give them to someone else.
for (auto iter = list.begin(); iter != list.end(); ) {
auto consider = iter++;
if (!(consider->val() % 7)) {
TakeThisObjectFromMe(list.erase(consider));
}
}
// Destroy the rest of the object by forcing the list to release its unique
// references to the objects. We could also simply let the list leave the
// scope of the function, which would do the same.
list.clear();
}
指標類型
第一個要注意的事項之一
std::
容器和 fbl::
容器是 fbl::
容器
利用指標追蹤物件尤其是在追蹤這些事件時,使用的是一組
明確支援的指標類型。定義 fbl::
清單的類型時
則會定義為物件型別的特定指標類型的清單。在本
範例,選擇 std::unique_ptr<>
代表
物件可以保存在本機,或由清單保留,但不能
目前有 3 種不同的指標類型
fbl::
容器允許:
T*
:沒有代管 RAII 語意的原始指標類型。std::unique_ptr<T, Deleter>
:標準專屬指標類型,可以是 使用自訂刪除器,或以預設的刪除器執行。fbl::RefPtr<T>
:fbl::
幹擾性參照指標。基本上是fbl::
的 免受干擾的std::shared_ptr<T>
版本
所有容器都必須告知容器持有的物件類型,以及
目前使用指標,透過
容器類型使用代管指標類型時,容器一律會採用
將物件新增至容器時參照的擁有權
物件從容器中移除時,您也會失去該參照的擁有權。
這項規則的例外狀況是 clear()
,因此會捨棄所有參照。
「原始」指標不具特殊擁有權語意,表示其完全 可確保物件在容器中持續運作。 應該能在容器中移除或清除時正確清理。
可列出/可包含的混合類別
如果物件必須儲存於其某個位置中的下一個/上一個指標,
這個節點的狀態嗎?清單如何找到節點?實際上
以下提供幾個控制此行為的方法:
都是用最簡單的方法這是衍生自 DoublyLinkedList
的
Listable
的混合式小幫手。和清單本身一樣,您必須
值結合物件型別和指標類型 (透過第一個範本)
引數。這些類型必須符合為清單定義指定的類型
機器學習是向機器提供資料和答案
讓機器自行探索規則的科學根據預設,清單會尋找其 Listable
的例項
並混合使用 物件來取得物件使用的節點狀態
簿記以上作業都是在編譯期間完成,而且不會造成執行階段負擔
協助找出物件中的節點狀態
疊代
fbl::
容器同時支援範圍導向迴圈疊代,以及
更經典的 begin()/end() 樣式。和 std::
容器一樣
以範圍為基礎的 列舉,物件的 l 值參照將會
。請務必說出 auto&
或 const auto&
迴圈中 (或甚至 MyObject&
) 加入迴圈,意味著最終結果不會是 auto
意外觸發物件的複製建構函式。
fbl::
容器疊代器也支援標準前置和後置表單
++
運算子的部分,您可以看到,這個運算子可用來視需要移除元素
只要在疊代範圍內選取即可這個範例使用了修正後表單
consider
會成為可能選擇移除的元素,iter
會指向清單中下一個需要考慮的元素。
當元素位於
請參考閱讀清單,進一步瞭解
如何選擇 Kubeflow Pipelines SDK 或 TFX如要以所有標準方式存取基礎物件,請使用
->
運算子或使用 (*iter).val()
樣式。原始指標
就算呼叫 &(*iter)
也能擷取到物件中保養
疊代器,因為這類指標是對物件的原始指標。不建議這麼做
方便您保存隨時儲存
控管物件的生命週期
移除元素
在本例中,元素移除後,會透過疊代器移除 清除。清除作業的結果會是 r 值參照 清單使用的指標類型。這個參考檔案可能已復原 並保留在本機指標執行個體中,但在本案例中是直接移動 加到某個外部函式的呼叫中,將 將物件從清單傳到外部函式。
clear()
是將元素從容器中移除的另一種方式,但將直接捨棄
所有元素參照,可能會刪除指向的物件
在整個過程中。
設定建構依附元件
如要使用 fbl::
容器,使用者必須同時包含
決定容器使用的適當標頭檔案,並且加入
依附於專案 BUILD.gn
檔案中的 fbl
程式庫。
以下是各種容器類型的必要檔案:
容器類型 | 包含陳述 |
---|---|
fbl::SinglyLinkedList<> |
#include <fbl/intrusive_single_list.h> |
fbl::DoublyLinkedList<> |
#include <fbl/intrusive_double_list.h> |
fbl::WAVLTree<> |
#include <fbl/intrusive_wavl_tree.h> |
fbl::HashTable<> |
#include <fbl/intrusive_hash_table.h> |
此外,使用者也必須將 //zircon/system/ulib/fbl
程式庫新增至 deps
或專案 BUILD.gn
檔案的 public_deps
部分。參考資料
屬於 deps
區段,在使用者撰寫
可執行檔,或只在其程式庫的私人部分使用 fbl
。如果
fbl
正用於使用者程式庫的公開標頭中的任何地方。
請改用 public_deps
。