一个智能指针类的构造函数需要几种
2010-10-29 12:11:06

2 Answers

// { // CVAAutoPtr<Foo> foo(new Foo("wee")); // } // { // CVAAutoPtr<Foo> foo; // foo.reset(new Foo("wee")); // foo.reset(new Foo("wee2")); // foo.reset(new Foo("wee3")); // foo->Method(); // foo.get()->Method(); // SomeFunc(foo.Release()); // foo.reset(new Foo("wee4")); // foo.reset(); // } template <typename C> class CVAAutoPtr { public: typedef C element_type; explicit CVAAutoPtr(C* p = NULL) : ptr_(p) { } ~CVAAutoPtr() {delete ptr_;} operator C*() const { return ptr_; } void reset(C* p = NULL) { if (p != ptr_) { delete ptr_; ptr_ = p; } } C& operator*() const { assert(ptr_ != NULL); return *ptr_; } C* operator->() const { assert(ptr_ != NULL); return ptr_; } C* get() const { return ptr_; } bool operator==(C* p) const { return ptr_ == p; } bool operator!=(C* p) const { return ptr_ != p; } void swap(CVAAutoPtr& p2) { C* tmp = ptr_; ptr_ = p2.ptr_; p2.ptr_ = tmp; } C* release() { C* retVal = ptr_; ptr_ = NULL; return retVal; } private: C* ptr_; template <class C2> bool operator==(CVAAutoPtr<C2> const& p2) const; template <class C2> bool operator!=(CVAAutoPtr<C2> const& p2) const; VA_DISALLOW_COPY_AND_ASSIGN_(CVAAutoPtr); }; ////////////////////////////////////////////////////// // T must be RefCounted,thread safe or not(but fast) ////////////////////////////////////////////////////// // class MyFoo : public RefCounted<MyFoo> { // ... // }; // void some_function() { // CVARefPtr<MyFoo> foo = new MyFoo(); // foo->Method(param); // } // // void some_other_function() { // CVARefPtr<MyFoo> foo = new MyFoo(); // ... // foo = NULL; // ... // if (foo) // foo->Method(param); // } // // { // CVARefPtr<MyFoo> a = new MyFoo(); // CVARefPtr<MyFoo> b; // // b.swap(a); // } // // { // CVARefPtr<MyFoo> a = new MyFoo(); // CVARefPtr<MyFoo> b; // b = a; // } // template <class T> class CVARefPtr { public: CVARefPtr() : ptr_(NULL) { } CVARefPtr(T* p) : ptr_(p) { if (ptr_) ptr_->AddRef(); } CVARefPtr(const CVARefPtr<T>& r) : ptr_(r.ptr_) { if (ptr_) ptr_->AddRef(); } ~CVARefPtr() { if (ptr_) ptr_->Release(); } T* get() const { return ptr_; } operator T*() const { return ptr_; } T* operator->() const { return ptr_; } CVARefPtr<T>& operator=(T* p) { if (p) p->AddRef(); if (ptr_ ) ptr_ ->Release(); ptr_ = p; return *this; } CVARefPtr<T>& operator=(const CVARefPtr<T>& r) { return *this = r.ptr_; } void swap(T** pp) { T* p = ptr_; ptr_ = *pp; *pp = p; } void swap(CVARefPtr<T>& r) { swap(&r.ptr_); } private: T* ptr_; };
2010-10-29 14:42:53

一、智能指针最常用的类是CComBSTR,它封装了BSTR类型字符串。BSTR是一个带长度前缀的OLECHAR类型字符串。从效率上考虑,解释环境都愿意使用长度前缀的字符串,比如VB、Java、VBScript、JScript。而OLECHAR是独立于语言、硬件结构的文本数据类型。BSTR有很多操作,使用CComBSTR来封装。
CComBSTR类提供八个构造函数:
1.CComBSTR(LPCOLESTR pSrc)
2.CComBSTR(int nSize,LPCOLESTR sz)
3.CComBSTR(int nSize)
4.CComBSTR(const CComBSTR& src)
5.BSTR Copy() const
6.CComBSTR(LPCSTR pSrc)
7.CComBSTR(int nSize,LPCSTR sz)
8.CComBSTR(REFGUID src)

二、对于要调用的方法不知道参数类型的时候,使用CComVariant,提供23种构造函数,网上搜下吧。

三、CComSafeArrayBound与CComVariant相同提供通用数据类型,不同的是提供通用数组。

四、CComPtr和CComQIPtr。CComPtr为特定类型的结构指针创建实例,如:
CComPtrpunk;
CComPtrpno;
CComQIPtr实现了CComPtr所有功能并对其进行了扩展。当把一个与智能指针不同的借口指针赋值给CComQIPtr实例时,CComQIPtr调用提供的接口指针的QueryInterface函数:
CComPtrpunk;
CComQIPtrpno=punk; //调用punk->QI(IID_INamedObject,...)

五、CAutoPtr、CAutoVectorPtr。看如下代码:
CMyClass::SomeFunc()
{
CFoo *pFoo=new Foo();
CAutoPtrspFoo(pFoo); //获得pFoo的所有权
spFoo->DoSomeFoo();
}//CAutoPtr在spFoo生命期结束时删除pFoo实例
这个函数实现了吧pFoo的所有权交给CAutoPtr,函数结束时对象自动销毁以及接管异常处理。
CAutoVectorPtr和CAutoPtr的不同在于,CAutoVectorPtr可以管理对象数组。

C++ ATL类库的智能指针是个很强大的东西,封装了很多功能,更重要的是跨语言和平台。

2010-10-29 15:33:03
您不能回答该问题或者回答已经关闭!

相关文章推荐

  • C#中using指令的几种用法

    using + 命名空间名字,这样可以在程序中直接用命令空间中的类型,而不必指定类型的详细命名空间,类似于Java的import,这个功能也是最常用的,几乎每个cs的程序都会用到

  • C#实例解析适配器设计模式

    将一个类的接口变成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够一起工作

  • 使用托管C++粘合C#和C++代码(二)

    本文实现一下C++代码调用C#代码的过程。我构造一个简单并且直观的例子:通过C++ UI 触发C# UI.

  • C#开发高性能Log Help类设计开发

    项目中要在操作数据库的异常处理中加入写Log日志,对于商业上有要求,写log时对其它操作尽可能影响小,不能因为加入log导致耗时太多

  • Async和Await使异步编程更简单

    C#5.0中async和await两个关键字,这两个关键字简化了异步编程,之所以简化了,还是因为编译器给我们做了更多的工作

  • C#开发中的反射机制

    反射的定义:审查元数据并收集关于它的类型信息的能力。元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等

  • C#运行时相互关系

    C#运行时相互关系,包括运行时类型、对象、线程栈和托管堆之间的相互关系,静态方法、实例方法和虚方法的区别等等

  • C#协变和逆变

    “协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型,“逆变”则是指能够使用派生程度更小的类型

  • C#基础概念之延迟加载

    延迟加载(lazy load)是Hibernate3关联关系对象默认的加载方式,延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作

  • C#中的索引器的简单理解和用法

    C#中的类成员可以是任意类型,包括数组和集合。当一个类包含了数组和集合成员时,索引器将大大简化对数组或集合成员的存取操作

  • 使用托管C++粘合C#和C++代码(一)

    C#在xml读写,数据库操纵,界面构造等很多方面性能卓越;C++的效率高,是底层开发的必备武器

  • 深入C# 序列化(Serialize)、反序列化(Deserialize)

    C#中的序列化和反序列化,序列化是.NET运行时环境用来支持用户定义类型的流化的机制