Item 15:Provide access to raw resources in resource-managing classes
資源管理類很棒。它們是你對抗資源泄露的堡壘。排除此等泄露是良好設計系統的根本性質。然而許多APIs直接指涉資源,所以除非你發誓永不錄用這樣的APIs,否則只得繞過資源管理對象直接訪問原始資源。
假如你使用智能指針保存factory函數createInvestment的調用結果:
std::tr1::shared_ptr<Investment> pInv(createInvestment());
假設你希望某個函數處理Investment對象,像這樣:
int daysHeld(const Investment* pi);
而你想要這麼調用它:
int days = daysHeld(pInv);
這樣卻通不過編譯,因爲daysHeld需要的是Investment*指針,你傳給它的卻是一個類型爲tr1::shared_ptr<Investment>的對象。
這個時候你需要一個函數可以將RAII class對象轉換爲其所含之原始資源。有兩個方法可以達成目標:顯示轉換和隱式轉換
只能指針tr1::shared _ptr和auto_ptr都提供一個get成員函數,用來執行顯示轉換,也就是它們會返回智能指針內部的原始指針(的復件):
int days = daysHeld(pInv.get());
此外,你也可以通過指針取值操作符(operator->和operator*),來隱式轉換至底部原始指針。
是否該提供一個顯示轉換函數將RAII class轉換爲其底部資源,或是應該提供隱式轉換,答案主要取決於RAII class被設計執行的特定工作,以及它被使用的情況。最佳設計是堅持條款18的忠告:讓接口容易被正確使用,不易被無用。通常顯示轉換函數如get是比較受歡迎的例子,因爲它將“非故意之類型轉換”的可能性最小化了。
請記住:
1.APIs往往要求訪問原始資源,所以每一個RAII class應該提供一個“取得其所管理之資源”的辦法。
2.對原始資源的訪問可能經由顯示轉換或隱式轉換。一般而言顯示轉換比較安全,但隱式轉換對客戶比較方便。