C++ smart pointer,unique_ptr,shared_ptr
发布日期:2021-05-06 19:47:46 浏览次数:22 分类:精选文章

本文共 3149 字,大约阅读时间需要 10 分钟。

C++ smart pointer,unique_ptr,shared_ptr

smart pointer

與一般的pointer相比,smart pointer的優勢在於我們不需要顯式地呼叫delete(ptr)來釋放它所佔用的記憶體。只要smart pointer一落在可視範圍之外,smart pointer的destructor便會自動地釋放動態分配的內存。

std::unique_ptr

我們可以將std::unique_ptr看成是raw pointer的container。當我們希望一塊資源只能被一個指標所存取時,我們就可以使用std::unique_ptr

C++不允許std::unique_ptr被複製。所以如果我們想要轉移資源的擁有者,就必須借助std::move來達成。

如:

//會出錯,不能複製unique_ptr unique_ptr ptr2 = ptr1;
//可以成功執行unique_ptr ptr2 = move(ptr1);

TensorRT/samples/opensource/sampleMNIST/sampleMNIST.cpp中有下面這麼一段:

template 
using SampleUniquePtr = std::unique_ptr
;

參照:

template <    class T,    class Deleter> class unique_ptr
;

可以得知samplesCommon::InferDeleter是這裡指定的deleter,在該unique_ptr被摧毀或指向別處時,deleter就會負責清理該unique_ptr所佔用的空間。

Deleter

上面定義的SampleUniquePtr是這麼被調用的:

SampleUniquePtr
mMeanBlob;

其中nvcaffeparser1::IBinaryProtoBlob來自TensorRT/include/NvCaffeParser.h

//!//! \class IBinaryProtoBlob//!//! \brief Object used to store and query data extracted from a binaryproto file using the ICaffeParser.//!//! \see nvcaffeparser1::ICaffeParser//!//! \warning Do not inherit from this class, as doing so will break forward-compatibility of the API and ABI.//!class IBinaryProtoBlob{   public:    virtual const void* getData() TRTNOEXCEPT = 0;    virtual nvinfer1::DimsNCHW getDimensions() TRTNOEXCEPT = 0;    virtual nvinfer1::DataType getDataType() TRTNOEXCEPT = 0;    virtual void destroy() TRTNOEXCEPT = 0;protected:    virtual ~IBinaryProtoBlob() {   }};

samplesCommon::InferDeleter定義於TensorRT/samples/common/common.h

struct InferDeleter{       template 
void operator()(T* obj) const { if (obj) { obj->destroy(); } }};

它會調用T型別(此處即為nvcaffeparser1::IBinaryProtoBlob)物件的destroy函數來銷毀該物件。

關於Deleter

Deleter must be FunctionObject or lvalue reference to a FunctionObject or lvalue reference to function, callable with an argument of type unique_ptr
::pointer

Deleter必須是一個functor,或是functor的左值引用,又或是函數的左值引用。由於InferDeleteroverride了()這個運算子,所以它確實是一個functor。

std::unique_ptr::get

TensorRT/parsers/caffe/caffeParser/caffeParser.cpp的函數CaffeParser::parse中使用了std::unique_ptr::get的語法:

mModel = std::unique_ptr
(new trtcaffe::NetParameter);//bool readBinaryProto(trtcaffe::NetParameter* net, const char* file, size_t bufSize)/**/readBinaryProto(mModel.get(), modelFile, mProtobufBufferSize))/**/

參考:

std::unique_ptr::getpointer get() const noexcept;

其作用為:

Returns the stored pointer.

即回傳std::unique_ptr內儲存的指標。

std::shared_ptr

std::shared_ptr亦是raw pointer的container。當我們希望一塊資源能被多個pointer所存取時,我們就會用到std::shared_ptr

C++允許多個shared_ptr指向同一塊資源。並且shared_ptr還自帶了計數功能,即,每當一個新的shared_ptr指向該資源時,reference count就會加一;而每當一個shared_ptr指向別處或是被銷毀時,reference count就會減一。

TensorRT/samples/opensource/sampleMNIST/sampleMNIST.cpp中對shared_ptr的使用:

std::shared_ptr
mEngine{ nullptr}; //!< The TensorRT engine used to run the network//...mEngine = std::shared_ptr
( builder->buildEngineWithConfig(*network, *config), samplesCommon::InferDeleter());

以下是的定義,可與上面的代碼相對照:

template< class Y, class Deleter >shared_ptr( Y* ptr, Deleter d );

參考連結

上一篇:C++ functor
下一篇:TensorRT/samples/common/argsParser.h源碼研讀

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2025年04月17日 03时02分32秒