/*
* allocator::value_type
* allocator::pointer
* allocator::const_pointer
* allocator::reference
* allocator::const_reference
* allocator::size_type
* allocator::difference_type
* allocator::rebind:一个嵌套的class template, 拥有唯一成员other
* allocator::allocator():默认构造函数
* allocator::allocator(const allocator&):拷贝构造
* allocator::~allocator()
* pointer allocator::address(reference x) 返回某个对象的地址,相当于&x
* const_pointer allocator::address(const_reference x) 返回某个const对象的地址
* pointer allocator::allocate(size_type n, const void* = 0) 配置空间,n个T空间,第二个是提示,可以依靠它来增加额外空间,或者忽略
* void allocator::deallocate(pointer p, size_type n) 归还先前的配置空间
* size_type alloctor::max_size() const 返回可配置的最大量
* void allocator::construct(pointer p, const T& x) 等同于;new(p) T(x)
* void alloctor::destory(pointer p) 等同于p-> ~T
*/
//通过以上接口编写一个自己的分配器
#include <new> //for placement new
#include <cstddef> //for ptrdiff_t, size_t
#include <cstdlib> //for exit()
#include <climits> // for UINT_MAX
#include <iostream>
namespace yxAlloc{
template<class T>
inline T* _allocate(ptrdiff_t size, T*)
{
set_new_handler(0);//检测内存是否足
T* tmp = (T*)(::operator new((size_t)(size * sizeof (T))));
if (0 == tmp)
{
std::cerr << "out of memory" << std::endl;
exit(1);
}
return tmp;
}
template <class T>
inline void _deallocate(T* p)
{
::operator delete(p);
}
template<class T1, class T2>
void _construct(T1* p, const T2& x)
{
new(p) T1(x);
}
template <class T>
void _destory(T* p)
{
p->~T();
}
template<class T>
class allocator{
public:
typedef T value_type;
typedef T* pointer;
typedef T& reference;
typedef const T* const_pointer;
typedef const T& const_reference;
typedef ptrdiff_t difference_type;
typedef size_t size_type;
// template<class U>
struct rebind{
typedef allocator<int> other;
};
pointer allocate(size_type n, const void* hint = nullptr)
{
return _allocate(static_cast<difference_type>(n), static_cast<pointer>(hint));
}
void deallocate(pointer p, size_type n)
{
_deallocate(p);
}
void construct(pointer p, const T& t)
{
_construct(p, t);
}
void destory(pointer p)
{
_destory(p);
}
size_type max_size() const {return (size_type)UINT_MAX/sizeof(T);}
pointer address(reference x)
{
return (pointer)&x;
}
const_pointer address(const_reference x)
{
return (const_pointer)&x;
}
};
}
//当然以上自己编写的分配器只能在VC, BC下使用,,,无法用在gcc中,因为sgi stl根本上脱离了stl
它是要生成的对应对象空间的个数,比如size * sizeof(T):生成size个T对象的空间;size类型一般为ptrdiff_t,一般用于定义两个指针的距离,,因为两个指针的加减,结果已经不再是指针,而是一种距离的概念,,因此C++引入ptrdiff_t的概念,相当于long int , size_t 可以理解为 long long unsigned int....。
第二个参数可有可无,需要增加空间的时候,可能会用到它,比如:const void* hint = 0;
set_new_handler(0)一般用于处理内存是否够;该分配器用operator new()函数进行分配空间,实质上就是使用malloc进行分配(我之前的new,delete文章有说明),因此会额外给它两个cookie空间,从而会浪费空间。
就是之前已经配置空间的地址,
无
使用::operator delete函数进行空间的回收,实质上就是使用free.
void_construct(T1* p,const T2& x){new(p)T1(x);}
这里使用的是placement new(所谓placement new就是在用户指定的内存位置上构建新的对象,这个构建过程不需要额外分配内存,只需要调用对象的构造函数即可。)比如上面的代码就调用T1::T1(x);(placement new是怎么做的呢,说白了就是把原本new做的两步工作分开来。第一步你自己分配内存,第二步你调用类的构造函数在自己分配的内存上构建新的对象。)
new(p)T1(x):就是在指针p的构建了一个T1的新的对象。可以节省空间,但是这就必须要显式调用析构函数所以就有了下面的函数
p->~T();,当然还有第二版本的,要判断trivial destuctor,我还没学到。
//即用{}进行数值初始化,要类型一致
double a = {1.23} //对
double b = {1} //对
double c = 1.2;
int d = {1.22} //错
//而不用花括号
int d = 1.22 //对,但是d = 1;
int d = (1.22) //对,但是d = 1;
如果定义变量时没有指定初值,则变量被默认初始化(default initialized),此时变量被赋予了“默认值”。默认值到底是什么由变量类型决定,同时定义变量的位置也会对此有影响。如果是内置类型的变量未被显式初始化,它的值由定义的位置决定。定义于任何函数之外的变量初始化为0;定义于函数体内的内置类型的对象如果没有初始化,则其值未定义。类的对象如果没有显式地初始化,则其值由类确定。
extern int i; //声明了i并未定义
int i ; //声明并且定义了i;
extern int i = 1; //定义了
//在函数体内部,如果试图初始化一个由extern关键字标记的变量,将引发错误。
//声明和定义的区别看起来也许微不足道,但实际上却非常重要。如果要在多个文件中使用同一个变量,
//就必须将声明和定义分离。此时,变量的定义必须出现在且只能出现在一个文件中,
//而其他用到该变量的文件必须对其进行声明,却绝对不能重复定义。
#include <iostream>
int reuse = 32;
int main()
{
int reuse = 0; //新建reuse,覆盖了全局reuse
cout << reuse << endl; //0
cout << ::reuse << endl; //32 强制全局
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。