ATL Internals 2ed复习.chapter 3.CAutoPtr
来源:互联网 发布:绿坝花季护航软件 编辑:程序博客网 时间:2024/05/29 16:23
ATL提供了CAutoPtr, CAutoVectorPtr, CAutoPtrArray, and CAutoPtrList,它们具有类似auto_ptr功能,而没有抛出异常,并且不需要借助于CRT库。
The CAutoPtr and CAutoVectorPtr Classes
例子:
STDMETHODIMP CMyClass::SomeFunc() { CFoo* pFoo = new Foo(); // instantiate C++ class CAutoPtr<CFoo> spFoo(pFoo); // take ownership of pFoo spFoo->DoSomeFoo(); // ... do other things with spFoo} // CAutoPtr deletes pFoo instance // when spFoo goes out of scope
下面以CAutoPtr为样板,其他智能指针功能类似
Constructors and Destructor
CAutoPtr() : m_p( NULL ) { } template< typename TSrc > CAutoPtr( CAutoPtr< TSrc >& p ) { m_p = p.Detach(); // Transfer ownership} CAutoPtr( CAutoPtr< T >& p ) { m_p = p.Detach(); // Transfer ownership} explicit CAutoPtr( T* p ) : m_p( p ) { }
注意4th类型,p可以为派生类
class CAnimal { ... };class CDog : public CAnimal { ... };//...CDog* pDog = new CDog();CAutoPtr<CAnimal> spAnimal(pDog);
~CAutoPtr() { Free(); } void Free() { delete m_p; m_p = NULL; }
CAutoPtr Operators
template< typename TSrc > CAutoPtr< T >& operator=( CAutoPtr< TSrc >& p ) { if(m_p==p.m_p) { ATLASSERT(FALSE); } else { Free(); Attach( p.Detach() ); // Transfer ownership } return( *this ); } CAutoPtr< T >& operator=( CAutoPtr< T >& p ) { if(*this==p) { if(this!=&p) { ATLASSERT(FALSE); p.Detach(); } else { } } else { Free(); Attach( p.Detach() ); // Transfer ownership } return( *this ); }
不管采用何种形态,首先检查指针是否指向同一个实例,然后Free(),再用Detach()转移释放权,避免多次delete
注意第一种形态,TSrc可以为T的衍生类,例子:
class CAnimal { ... };class CDog : public CAnimal { ... };// ...// instantiate a CAnimalCAutoPtr<CAnimal> spAnimal(new CAnimal());// instantiate a CDogCAutoPtr<CDog> spDog(new CDog());// CAnimal instance freed herespAnimal = spDog;// ... CDog instance will be freed when spAnimal// goes out of scope
类重新定义了->操作:
operator T*() const { return( m_p ); } T* operator->() const { ATLASSERT( m_p != NULL ); return( m_p ); }
例子:
class CDog {public: void Bark() {} int m_nAge;};CAutoPtr<CDog> spDog(new Dog);spDog->Bark();spDog->m_nAge += 5;
比较操作符:
bool operator!=(CAutoPtr<T>& p) const { return !operator==(p); }bool operator==(CAutoPtr<T>& p) const { return m_p==p.m_p; }
CAutoVectorPtr
和CAutoPtr相比,有多点不同:
CAutoVectorPtr不能使用派生类指针进行赋值
CAutoVectorPtr使用Allocate进行集合构造,类似于new[]:
bool Allocate( size_t nElements ) { ATLASSERT( m_p == NULL ); ATLTRY( m_p = new T[nElements] ); if( m_p == NULL ) { return( false ); } return( true ); }
例子:
class CAnimal { public: void Growl() {} };// each instance is of type CAnimalCAutoVectorPtr<CAnimal> spZoo;// allocate and initialize 100 CAnimal'sspZoo.Allocate(100);
注意,该类没有重载->操作符,所以下面的代码是错误的:
spZoo->Growl(); // wrong! can't do this => doesn't make sense
而且,ATL并没有重载operator[],所以必须要使用下面的形式:
((CAnimal*)spZoo)[5].Growl();
而且,ATL只接受带有默认构造函数的类,所以下面的代码是错误的:
class CAnimal {public:CAnimal(int nAge) : m_nAge(nAge) {} void Growl() {}private:int m_nAge;}CAutoVectorPtr<CAnimal> spZoo;spZoo.Allocate(100); // won't compile => no default constructor
注意,析构函数使用了delete[]来释放内存,对应的只能是Allocate(),所以如果用户使用了Attach(),就会造成麻烦:
class CAnimal {};// allocate only a single instanceCAnimal* pAnimal = new Animal;CAutoVectorPtr<CAnimal> spZoo;// wrong, wrong!!! pAnimal is not a collectionspZoo.Attach(pAnimal)
- ATL Internals 2ed复习.chapter 3.CAutoPtr
- ATL Internals 2ed复习.chapter 3.ATL Memory Managers
- ATL Internals 2ed复习.chapter 2
- ATL Internals 2ed复习.chapter 3.CComVariant
- ATL Internals 2ed复习.chapter 3.SAFEARRAY
- ATL Internals 2ed复习.chapter 3.CComSafeArray
- ATL Internals 2ed复习.chapter 3.CComPtr CComQIPtr
- ATL Internals 2ed复习.chapter 3.CComGITPtr
- ATL Internals 2ed复习.chapter 7.ATL Persistence implements
- ATL Internals 2ed复习.chapter 4.Thread
- ATL Internals 2ed复习.chapter 4.IUnknown
- ATL Internals 2ed复习.chapter 4.Creators
- ATL Internals 2ed复习.chapter 4.Debugging
- ATL Internals 2ed复习.chapter 5.COM Server review
- ATL Internals 2ed复习.chapter 5.Object Map
- ATL Internals 2ed复习.chapter 5.CAtlModule
- ATL Internals 2ed复习.chapter 6.Table driven QueryInterface
- ATL Internals 2ed复习.chapter 6.interface map tricks
- 配置VIM做PHP的IDE开发环境
- c语言实现双链表
- linux基础之spi驱动程序理解
- PostgreSQL与MySQL比较
- 完全二叉树与满二叉树
- ATL Internals 2ed复习.chapter 3.CAutoPtr
- 失恋了,记录下心理路程
- 话说软件详细设计工具
- int、int.Parse()、int.TryParse()、Int32.Parse()、Int32.TryParse()、Convert.ToInt32()区别
- socket通信之最简单的socket通信
- IOS开发中委托代理(degegate)的理解和使用示例
- 关于linux设备模型kobject,kset,ktype
- VS2010与.NET4系列 6.ASP.NET,HTML,JavaScript片断支持
- pthread_join