本文共 4344 字,大约阅读时间需要 14 分钟。
class Ptr -
Template class for smart reference-counting pointers
template class Ptr{ public: // default constructor Ptr(); // constructor that wraps the object pointer Ptr(_Tp* _obj); // destructor: calls release() ~Ptr(); // copy constructor; increments ptr's reference counter Ptr(const Ptr& ptr); // assignment operator; decrements own reference counter // (with release()) and increments ptr's reference counter Ptr& operator = (const Ptr& ptr); // increments reference counter void addref(); // decrements reference counter; when it becomes 0, // delete_obj() is called void release(); // user-specified custom object deletion operation. // by default, "delete obj;" is called void delete_obj(); // returns true if obj == 0; bool empty() const; // provide access to the object fields and methods _Tp* operator -> (); const _Tp* operator -> () const; // return the underlying object pointer; // thanks to the methods, the Ptr<_Tp> can be // used instead of _Tp* operator _Tp* (); operator const _Tp*() const;protected: // the encapsulated object pointer _Tp* obj; // the associated reference counter int* refcount;};
The Ptr<_Tp> class is a template class that wraps pointers of the corresponding type. It is similar toshared_ptr that is part of the Boost library ( ) and also part of the standard.
This class provides the following options:
- Default constructor, copy constructor, and assignment operator for an arbitrary C++ class or a C structure. For some objects, like files, windows, mutexes, sockets, and others, a copy constructor or an assignment operator are difficult to define. For some other objects, like complex classifiers in OpenCV, copy constructors are absent and not easy to implement. Finally, some of complex OpenCV and your own data structures may be written in C. However, copy constructors and default constructors can simplify programming a lot. Besides, they are often required (for example, by STL containers). By wrapping a pointer to such a complex object TObj toPtr<TObj> , you automatically get all of the necessary constructors and the assignment operator.
- O(1) complexity of the above-mentioned operations. While some structures, like std::vector, provide a copy constructor and an assignment operator, the operations may take a considerable amount of time if the data structures are large. But if the structures are put into Ptr<> , the overhead is small and independent of the data size.
- Automatic destruction, even for C structures. See the example below with FILE* .
- Heterogeneous collections of objects. The standard STL and most other C++ and OpenCV containers can store only objects of the same type and the same size. The classical solution to store objects of different types in the same container is to store pointers to the base classbase_class_t* instead but then you loose the automatic memory management. Again, by usingPtr<base_class_t>() instead of the raw pointers, you can solve the problem.
The Ptr class treats the wrapped object as a black box. The reference counter is allocated and managed separately. The only thing the pointer class needs to know about the object is how to deallocate it. This knowledge is incapsulated in the Ptr::delete_obj() method that is called when the reference counter becomes 0. If the object is a C++ class instance, no additional coding is needed, because the default implementation of this method calls delete obj; . However, if the object is deallocated in a different way, the specialized method should be created. For example, if you want to wrap FILE , thedelete_obj may be implemented as follows:
template<> inline void Ptr ::delete_obj(){ fclose(obj); // no need to clear the pointer afterwards, // it is done externally.}...// now use it:Ptr f(fopen("myfile.txt", "r"));if(f.empty()) throw ...;fprintf(f, ....);...// the file will be closed automatically by the Ptr destructor.
Note
The reference increment/decrement operations are implemented as atomic operations, and therefore it is normally safe to use the classes in multi-threaded applications. The same is true for and other C++ OpenCV classes that operate on the reference counters.
转载地址:http://benws.baihongyu.com/