判斷智能指針是否為 NULL


測試智能指針是否為 NULL

在Qt的項目中,osg里有智能指針

osg::ref_ptr<int> a;

然后可能和C++標准庫不同 ,在判斷智能指針是否為空的時候

以下來自與《More Effective C++》 ,讀了覺得很有收獲

文尾有我看VS2019的MSVC2017中的頭文件 和 osg的

但是有一件我們做不到的事情是“發現靈巧指針為 NULL”:

SmartPtr<TreeNode> ptn; 

if (ptn == 0) ...                    // error! 
if (ptn) ...                         // error! 
if (!ptn) ...                        // error! 

這是一個嚴重的限制。

在靈巧指針類里加入一個 isNull 成員函數是一件很容易的事

但是沒有解決當測試NULL 時靈巧指針的行為與 dumb pointer(即普通指針) 不相似的問題。

另一種方法是提供隱式類型轉換操作符,允許編譯上述的測試。一般應用於這種目的的類型轉換是 void* :

template<class T> 
class SmartPtr { 
public: 
  ... 
  operator void*();                  // 如果靈巧指針為 null, 
  ...                                // 返回 0, 否則返回 
};                                   // 非 0。 
SmartPtr<TreeNode> ptn; 
... 
if (ptn == 0) ...                    // 現在正確 
if (ptn) ...                         // 也正確 
if (!ptn) ...                        // 正確 

這與 iostream 類中提供的類型轉換相同,所以可以這樣編寫代碼:

ifstream inputFile("datafile.dat"); 
if (inputFile) ...                   // 測試 inputFile 是否已經被 
                                     // 成功地打開。 

像所有的類型轉換函數一樣,它有一個缺點:在一些情況下雖然大多數程序員希望它調
用失敗,但是函數確實能夠成功地被調用(參見條款 M5)。特別是它允許靈巧指針與完全不
同的類型之間進行比較:

SmartPtr<Apple> pa; 
SmartPtr<Orange> po; 
... 
if (pa == po) ...                    // 這能夠被成功編譯! 

即使在 SmartPtr 和 SmartPtr 之間沒有 operator= 函數,也能夠編譯,
因為靈巧指針被隱式地轉換為 void 指針,而對於內建指針類型有內建的比較函數。這種進
行隱式類型轉換的行為特性很危險。(再回看一下條款 M5,必須反反復復地閱讀,做到耳熟
能詳。)
在 void
類型轉換方面,也有一些變化。有些設計者采用到 const void*的類型轉換,
還有一些采取轉換到 bool 的方法。這些變化都沒有消除混合類型比較的問題。
有一種兩全之策可以提供合理的測試 null 值的語法形式,同時把不同類型的靈巧指針
之間進行比較的可能性降到最低。

這就是在靈巧指針類中重載 operator!,當且僅當靈巧指針是一個空指針時,operator!返回 true:

template<class T> 
class SmartPtr { 
public:   ... 
  bool operator!() const;            // 當且僅當靈巧指針是 
  ...                                // 空值,返回 true。 
}; 
用戶程序如下所示: 
SmartPtr<TreeNode> ptn; 
... 
if (!ptn) {                          // 正確 
  ...                                // ptn 是空值 
} 
else { 
  ...                                // ptn 不是空值 
} 
但是這樣就不正確了: 
if (ptn == 0) ...                    // 仍然錯誤 
if (ptn) ...                         // 也是錯誤的 
僅在這種情況下會存在不同類型之間進行比較: 
SmartPtr<Apple> pa; 
SmartPtr<Orange> po; 
... 
if (!pa == !po) ...                 // 能夠編譯


 

幸好程序員不會經常這樣編寫代碼。

有趣的是,iostream 庫的實現除了提供 void隱式
的類型轉換,也有 operator!函數,不過這兩個函數通常測試的流狀態有些不同。

(在 C++類庫標准中(參見 Effective C++ 條款 49 和本書條款 M35)

,void*隱式的類型轉換已經被bool 類型的轉換所替代,operator bool 總是返回與 operator!相反的值。)

而在osg中也有重載operator!

圖片不貼了

但是在VS里面沒有


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM