1 /* -*- Mode: C++ -*- */ 2 3 /** 4 * @file icptrholder.h 5 * @author wyau (08/29/02) 6 * @brief C++ template classes for managing C++ pointers returned by VComponent::get_..._component, 7 * VComponent::get_..._property, ICalPropety::get_..._value. 8 * @remarks VComponent::get... functions returns a C++ oject that wraps the libical implementation. 9 * It is important to note that the wrapped implementation still belongs to the orginal 10 * component. To stop memory leak, caller must delete the pointer. However, the destructor 11 * will call the appropriate free function. eg. ~VComponent calls icalcomponent_free(imp). 12 * As stated previously, imp stil belongs to the original component. To avoid freeing the 13 * wrapped "imp", caller must set the "imp" to null before deleting the pointer. 14 * 15 * The template class relieves the burden of memory management when used as a stack based 16 * object. The class holds a pointer to the C++ Wrapper. The destructor set the imp to 17 * null before deleting the pointer. 18 * 19 * Each C++ Wrapper instantiates a template class in it's corresponding .h file. 20 * 21 * Usage example: 22 * VComponentTmpPtr p; // VComponentTmpPtr is an instantiation of this template 23 * for (p=component.get_first_component; p!= NULL; p=component.get_next_component) { 24 * 25 * (C) COPYRIGHT 2001, Critical Path 26 27 This program is free software; you can redistribute it and/or modify 28 it under the terms of either: 29 30 The LGPL as published by the Free Software Foundation, version 31 2.1, available at: http://www.fsf.org/copyleft/lesser.html 32 33 Or: 34 35 The Mozilla Public License Version 1.0. You may obtain a copy of 36 the License at http://www.mozilla.org/MPL/ 37 */ 38 39 #ifndef __ICPTRHOLDER_H__ 40 #define __ICPTRHOLDER_H__ 41 42 template<class T> class ICPointerHolder { 43 public: ICPointerHolder()44 ICPointerHolder() { ptr = NULL; } ICPointerHolder(T * p)45 ICPointerHolder(T* p) { ptr = p; } 46 47 // copy constructor to support assignment ICPointerHolder(const ICPointerHolder & ip)48 ICPointerHolder(const ICPointerHolder& ip) { 49 ptr = ip.ptr; 50 51 // We need to transfer ownership of ptr to this object by setting 52 // ip's ptr to null. Otherwise, ptr will de deleted twice. 53 // const ugliness requires us to do the const_cast. 54 ICPointerHolder *ipp = const_cast<ICPointerHolder*>(&ip); 55 ipp->ptr = NULL; 56 }; 57 ~ICPointerHolder()58 ~ICPointerHolder() { 59 release(); 60 } 61 62 ICPointerHolder& operator=(T* p) { 63 this->release(); 64 ptr = p; 65 return *this; 66 } 67 68 ICPointerHolder& operator=(ICPointerHolder& p) { 69 this->release(); 70 ptr = p.ptr; // this transfer ownership of the pointer 71 p.ptr = NULL; // set it to null so the pointer won't get delete twice. 72 return *this; 73 } 74 75 int operator!=(T* p) {return (ptr != p);} 76 int operator==(T* p) {return (ptr == p);} 77 78 operator T*() const { 79 return ptr; 80 } 81 82 T* operator->() const { 83 assert(ptr); 84 return ptr; 85 } 86 87 T& operator*() { 88 assert(ptr); 89 return *ptr; 90 } 91 92 private: release()93 void release() { 94 if (ptr != NULL) { 95 ptr->detach(); 96 delete ptr; 97 ptr = NULL; 98 } 99 } 100 101 T* ptr; 102 }; 103 104 #endif 105