- TypeTraits
类型萃取使用模板技术来萃取类型(包含自定义类型和内置类型)的某些特性,用以判断该类型是否含有某些特性,从而在泛型算法中来对该类型进行特殊的处理用来提高效率或者其他。
类型萃取是代码复用的一个非常有效的手段,有时候在我们写模板类或者函数时,处理相似的问题可能就一小部分的代码需要进行不同的处理,其他部分的逻辑都是相同的,这时类型萃取就可以做到很好的代码复用,我们能通过类型萃取拿到对应的类型从而只对这一部分的内容进行修改,从而达到了代码复用和很高的效率。在github和STL中源代码也用到了类型萃取,可见类型萃取在有些时候还是很好用的。
#include<iostream>
#include<string>
using namespace std;
struct __TrueType{};
struct __FalseType{};
template<class T>
struct __TypeTraits
{
typedef __FalseType Type;
};
template<>
struct __TypeTraits<int>
{
typedef __TrueType Type;
};
template<>
struct __TypeTraits<char>
{
typedef __FalseType Type;
};
template<>
struct __TypeTraits<string>
{
typedef __FalseType Type;
};
template<class T>
void __Copy( T valuetype,__FalseType)
{
cout << " __FalseType" << endl;
}
template<class T>
void __Copy(T valuetype,__TrueType)
{
cout << " __TrueType" << endl;
}
template<class T>
void Copy(T valueType)
{
__Copy(valueType,__TypeTraits<T>::Type());
}
int main()
{
int a = 0;
string s = " ";
Copy(a);
Copy(s);
return 0;
}
上述例子的图示分析:
这里我们拿到了我们传进去的类型是什么,从而在不同的__Copy()作出不同的处理方式,我这里只是打印一句话。比如当类型是int时我们可以用memcpy(),进行浅拷贝,当类型是string时我们进行深拷贝,这样就只有这部分进行少量的处理而不去重写其他部分的代码。
- Smart Pointer
智能指针:
智能指针就是智能的,自动的管理指针所指向的动态开辟的资源进行释放。而它用到的思想就是RAII,资源分配即初始化,定义一个类来封装资源的分配和释放,在构造函数完成资源的分配和初始化,在析构函数完成资源的清理,可以保证资源的正确初始化和释放。
其实
智能指针就是用一个类封装了一个指针,用构造初始化这个指针,用析构来释放这个指针,在重载operator*和operator->来模拟指针的功能。
智能指针的历史:
下面是shared_ptr的简单实现
template<class T>
class Sharedptr
{
public:
Sharedptr(T* ptr = NULL)
:_ptr(ptr)
,_refCount(new int(1))
{}
//this(sp)
Sharedptr(const Sharedptr<T>&sp)
:_ptr(sp._ptr)
, _refCount(sp._refCount)
{
(*sp._refCount)++;
}
//this=sp
Sharedptr<T>& operator=(const Sharedptr<T> sp)
{
if (_ptr != sp._ptr)
{
if (--(*_refCount) == 0)
{
delete _ptr;
delete _refCount;
_ptr = NULL;
_refCount = NULL;
}
++(*sp._refCount);
_ptr = sp._ptr;
_refCount = sp._refCount;
}
return *this;
}
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
~Sharedptr()
{
if (--(*_refCount)==0)
{
cout << "~Sharedptr()" << " ";
delete _ptr;
delete _refCount;
_ptr = NULL;
_refCount = NULL;
}
cout << endl;
}
private:
T* _ptr;
int* _refCount;
};
上述就是shared_ptr的基本实现,但是同样的它带来的一些问题,即循环引用问题。如下图分析:
代码实现如下:
// 前置声明
template<class T>
class WeakPtr;
template<class T>
class Sharedptr
{
friend class WeakPtr<T>;
public:
Sharedptr(T* ptr = NULL)
:_ptr(ptr)
,_refCount(new int(1))
{}
//this(sp)
Sharedptr(const Sharedptr<T>&sp)
:_ptr(sp._ptr)
, _refCount(sp._refCount)
{
(*sp._refCount)++;
}
//this=sp
Sharedptr<T>& operator=(const Sharedptr<T> sp)
{
if (_ptr != sp._ptr)
{
if (--(*_refCount) == 0)
{
delete _ptr;
delete _refCount;
_ptr = NULL;
_refCount = NULL;
}
++(*sp._refCount);
_ptr = sp._ptr;
_refCount = sp._refCount;
}
return *this;
}
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
~Sharedptr()
{
if (--(*_refCount)==0)
{
cout << "~Sharedptr()" << " ";
delete _ptr;
delete _refCount;
_ptr = NULL;
_refCount = NULL;
}
cout << endl;
}
int UseCount()
{
return *_refCount;
}
private:
T* _ptr;
int* _refCount;
};
template<class T>
class WeakPtr
{
public:
WeakPtr()
:_ptr(NULL)
{}
WeakPtr(const SharedPtr<T>& sp)
:_ptr(sp._ptr)
{}
WeakPtr<T>& operator=(const SharedPtr<T>& sp)
{
_ptr = sp._ptr;
return *this;
}
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
private:
T* _ptr;
};