程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++句柄解析,句柄解析

C++句柄解析,句柄解析

編輯:C++入門知識

C++句柄解析,句柄解析


C++句柄類解析

  引題:在C++中,對於運行時類型識別問題。在程序中使用引用或者指針在運行時動態識別對象類型。然而使用指針或者引用卻增加了用戶負擔(在繼承體系中,沒有明確的基類到派生類的轉換,必須用戶顯示轉換並將結果對象加入容器中。但是這樣的做法結果卻是派生對象部分成員是未初始化的)。

對於這一問題,可以將對象指針 保存在容器中來解決。但此時,用戶必須明確容器中指針和 對象的同步性(不能只有指針而對象不存在或者收指針不存在,對象存在)。

更好的解決方案就是句柄類了:

  C++ 中一個通用的技術是定義包裝(cover)類或句柄類。句柄類存儲和管 理基類指針。指針所指對象的類型可以變化,它既可以指向基類類型對象又可以 指向派生類型對象。用戶通過句柄類訪問繼承層次的操作。因為句柄類使用指針 執行操作,虛成員的行為將在運行時根據句柄實際綁定的對象的類型而變化。因 此,句柄的用戶可以獲得動態行為但無須操心指針的管理。

  包裝了繼承層次的句柄有兩個重要的設計考慮因素:

  • 對任何保存指針的類一樣,必須確定對復制控制做些什 麼。包裝了繼承層次的句柄通常表現得像一個智能指針 或者像一個值。
  • 句柄類決定句柄接口屏蔽還是不屏蔽繼承層次,如果不屏蔽繼承層次,用 戶必須了解和使用基本層次中的對象。

①指針型句柄:

  句柄包裝指針,用戶可以將該句柄類當作指針使用,卻不用去管理指針指向的對象。(句柄類更像是一個中介控制者)

定義方案:

1. 使用類包裝指針,包裝計數器(每個對象都有各自的這兩個成員)

2.使用類包裝指針,包裝計數器指針(資源和計數器共享)

 

句柄類除了定義構造,拷貝構造,賦值,還需要定義引用,解引用(使之看起來更像是指針)

對於構造函數:

1個默認構造函數初始化成員為0;

1個構造函數聲明指定對象類型的句柄。

那麼問題來了,如果用戶並不知曉用 繼承體系中具體哪個層次對象進行初始化,如何做呢。

解決這個問題的通用方法是定義虛操作進行復制,我們稱將 該操作命名為 clone。(克隆):

  對於繼承層次中的每個類,增加一個虛克隆函數eg:

class Item_base 
{
 public: 
    virtual Item_base* clone() const 
    { 
        return new Item_base(*this);
     }
 };    

有了克隆函數那麼 句柄類的定義如下:

Sales_item::Sales_item(const Item_base &item):
    p(item.clone()), use(new std::size_t(1)) 
{ }

對於繼承層次中  如果需要邏輯比較函數,一個好的做法是 定義內部比較,比較內部核心成員。

inline bool
compare(const Sales_item &lhs, const Sales_item &rhs)
{
    return lhs->book() < rhs->book();
}

使用帶關聯容器的比較器

要有效地工作,關聯容器需要對每個操作使用同一比較函數。然而,期望用 戶每次記住比較函數是不合理的,尤其是,沒有辦法檢查每個調用使用同一比較 函數。因此,容器記住比較函數是有意義的。通過將比較器存儲在容器對象中, 可以保證比較元素的每個操作將一致地進行。

這種做法,實質上就是使用函數指針,函數回調實現真正的比較。

// type of the comparison function used to order the multiset

typedef bool (*Comp)(const Sales_item&, const Sales_item&);

關聯容器的每個構造函數使我們能夠提供比較函數的名 字。可以這樣定義使用 compare 函數的空 multiset:

std::multiset<Sales_item, Comp>  items(compare);

multiset 是STL中的聯合容器。。在頭文件<set>中,具體用法請參看《STL源碼剖析》

 

參考(C++primer)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved