![]() |
Home | Libraries | People | FAQ | More |
As previously mentioned, Boost.Intrusive containers
are non-copyable and non-assignable, because
intrusive containers don't allocate memory at all. To implement a copy-constructor
or assignment operator, the user must clone one by one all the elements of
the container and insert them in another intrusive container. However, cloning
by hand is usually more inefficient than a member cloning function and a specialized
cloning function can offer more guarantees than the manual cloning (better
exception safety guarantees, for example).
前面提到,Boost.Intrusive 容器是不可複製和不可賦值的,
因為介入式容器根本不進行內存分配。要實現一個複製構造函數或賦值操作符,用戶必須從容器逐個對象進行克隆並將它們插入到另一個介入式容器中。但是,手工
進行克隆通常要比成員克隆函數低效,而且一個專門的克隆函數可以提供比手工克隆更多的保證(例如,更好的異常安全性保證)。
To ease the implementation of copy constructors and assignment operators of
classes containing Boost.Intrusive containers,
all Boost.Intrusive containers offer a special
cloning function called clone_from.
為了便於包含有 Boost.Intrusive 容器的類實現複製構造函數和賦值操作符,所有 Boost.Intrusive 容器都提供了一個名為 clone_from 的專用克隆函數。
Apart from the container to be cloned, clone_from
takes two function objects as arguments. For example, consider the clone_from member function of list:
除了要進行克隆的容器之外,clone_from
還有兩個函數對像參數。例如,list 的 clone_from 成員函數:
template <class Cloner, class Disposer> void clone_from(const list &src, Cloner cloner, Disposer disposer);
This function will make *this
a clone of src. Let's explain
the arguments:
該函數把 *this
變為 src 的克隆。下面解釋一下這些參數:
value_type
objects and return a pointer to the clone. It must implement the following
function: pointer operator()(const value_type &).value_type 對象並返回一個克隆物的指針。它必須實現以下函數:pointer operator()(const value_type &)。
value_type objects. It's used first to
empty the container before cloning and to dispose the elements if an exception
is thrown.value_type 對象的函數對象。用於在克隆之前清空容器,以及當有異常拋出時對元素進行處置。
The cloning function works as follows:
克隆函數工作如下:
Here's an example of clone_from:
以下是一個 clone_from 例子:
#include <boost/intrusive/list.hpp> #include <iostream> #include <vector> using namespace boost::intrusive; //A class that can be inserted in an intrusive list 一個可以插入到介入式鏈表中的類
class my_class : public list_base_hook<> { public: friend bool operator==(const my_class &a, const my_class &b) { return a.int_ == b.int_; } int int_; //...
}; //Definition of the intrusive list 介入式鏈表的定義
typedef list<my_class> my_class_list; //Cloner object function 克隆器函數對像
struct new_cloner { my_class *operator()(const my_class &clone_this) { return new my_class(clone_this); } }; //The disposer object function 處置器函數對像
struct delete_disposer { void operator()(my_class *delete_this) { delete delete_this; } }; int main() { const int MaxElem = 100; std::vector<my_class> nodes(MaxElem); //Fill all the nodes and insert them in the list 填充所有節點並插入到鏈表中
my_class_list list; for(int i = 0; i < MaxElem; ++i) nodes[i].int_ = i; list.insert(list.end(), nodes.begin(), nodes.end()); //Now clone "list" using "new" and "delete" object functions 現在使用 "new" 和 "delete" 函數對像克隆 "list"
my_class_list cloned_list; cloned_list.clone_from(list, new_cloner(), delete_disposer()); //Test that both are equal 測試兩個容器是否相等
if(cloned_list != list) std::cout << "Both lists are different" << std::endl; else std::cout << "Both lists are equal" << std::endl; //Don't forget to free the memory from the second list 不要忘記釋放第二個鏈表的內存
cloned_list.clear_and_dispose(delete_disposer()); return 0; }