- 构造和析构的基本工具
- 1.construct
- 2. destroy
- 2.1普通版本
- 2.2 类型萃取版本
- 源代码
对placement new包装
// 包装 placement new templateinline void construct(T1* p, const T2& val) { new (p) T1(val); } // 无参的 template inline void construct(T* p) { new (p) T(); }
有了这两个函数,就可以使用construct来对指定位置构造值。
示例:
int main(void)
{
int* p = (int*)malloc(sizeof(int));
Srh::construct(p, 100);
cout << *p << endl;
return 0;
}
2. destroy
2.1普通版本
两个版本,一个是对单个对象析构,一个是对迭代器范围内的对象析构。
那么就有这样一个问题,如果这迭代器范围内的对象,其析构过程是无关紧要的,那么这样编写就会影响效率。
// 析构对象 template2.2 类型萃取版本inline void destroy(T* p) { p->~T(); } // 析构范围内的对象 template inline void destroy(_FI _F, _FI _L) { for (; _F != _L; ++F) { destroy(&*_F); //(*_F)表示迭代器所指之物, // (&*_F)表示迭代器所指之物的地址 } }
通过类型萃取来看要析构的对象是否是无关紧要的。
流程:
- 调用 destroy(),通过value_type(_F)来获取迭代器所指之物的类型。
- __destroy()来得知T的值类型的析构函数是否是无关紧要的。
- 如果为真,那么就调用下面第一个函数,什么都不执行。
- 如果为假,就调用第二个函数,对迭代器范围内的对象析构。
// 如果析构函数无关紧要,那么就不需要上面这样麻烦 // 那么利用上面已知的true/false来判断 templateinline void __destroy_aux(_FI _F, _FI _L, Srh::__true_type) {} template inline void __destroy_aux(_FI _F, _FI _L, Srh::__false_type) { for (; _F != _L; ++_F) { destroy(&*_F); } } template inline void __destroy(_FI _F, _FI _L, T*) { // 得知T所指之物的值类型 // 再根据类型萃取 获取 值类型的析构函数是 true还是false typedef typename Srh::__type_traits ::has_trivial_destructor dest; __destroy_aux(_F, _L, dest()); } template inline void destroy(_FI _F, _FI _L) { // 调用下面的__destroy,获取_F迭代器所指之物的类型 __destroy(_F, _L, Srh::value_type(_F)); }
示例:
class Object
{
private:
int value;
public:
Object(int x = 0) : value(x) {
cout << "Object::create: " << value << endl;
}
~Object() {
cout << "Object::destroy" << endl;
}
};
int main(void)
{
const int n = 10;
Object* op = (Object*)malloc(sizeof(Object) * n);
for (int i = 0; i < n; ++i)
{
Srh::construct(&op[i], i);
}
Srh::destroy(op, op + n);
free(op);
return 0;
}
运行结果
原因是在type_traits中,对设计的类型的析构函数都是有关紧要的。
struct __true_type {};
struct __false_type {};
template
struct __type_traits
{
typedef __true_type this_dummy_member_must_be_first;
typedef __false_type has_trivial_default_constructor;
typedef __false_type has_trivial_copy_constructor;
typedef __false_type has_trivial_assignment_operator;
// 有关紧要的
typedef __false_type has_trivial_destructor;
typedef __false_type is_POD_type;
};
因此,可以对其提供一个特化版本:
template<> struct Srh::__type_traits
并在destroy函数里打印T的类型,方便得知是什么类型调用该函数。
templateinline void __destroy(_FI _F, _FI _L, T*) { cout << typeid(T).name() << endl; Srh::__type_traits (); typedef typename Srh::__type_traits ::has_trivial_destructor dest; __destroy_aux(_F, _L, dest()); }
运行结果:
源代码#ifndef MY_CONSTRUCT_H
#define MY_CONSTRUCT_H
#include"my_iterator.h"
#include"my_type_traits.h"
namespace Srh
{
// 包装定位new placement new
template
inline void construct(T1* p, const T2& val)
{
new (p) T1(val);
}
// 无参的
template
inline void construct(T* p)
{
new (p) T();
}
// 析构对象
template
inline void destroy(T* p)
{
p->~T();
}
// 如果析构函数无关紧要,那么就不需要上面这样麻烦
// 那么利用上面已知的true/false来判断
template
inline void __destroy_aux(_FI _F, _FI _L, Srh::__true_type)
{}
template
inline void __destroy_aux(_FI _F, _FI _L, Srh::__false_type)
{
for (; _F != _L; ++_F)
{
destroy(&*_F);
}
}
template
inline void __destroy(_FI _F, _FI _L, T*)
{
// 得知T所指之物的值类型
// 再根据类型萃取 获取 值类型的析构函数是 true还是false
typedef typename Srh::__type_traits::has_trivial_destructor dest;
__destroy_aux(_F, _L, dest());
}
template
inline void destroy(_FI _F, _FI _L)
{
// 调用下面的__destroy,获取_F迭代器所指之物的类型
__destroy(_F, _L, Srh::value_type(_F));
}
}
#endif



