文章标题
2017-04-22 16:42
281 查看
STL源码分析2.1
2.1.1设计一个简单的空间配置器
#ifndef SIMPLESTL_H_ #define SIMPLESTL_H_ #include <new> #include <cstddef> #include <cstdlib> #include <climits> #include <iostream> namespace JJ { template<typename T> inline T* _allocate(ptrdiff_t size, T*) { //函数原型为set_new_handler(x) //x是一个函数指针,当new不成功时回调x函数.当x为0时,表示回调函数为空的 //这个时候若new失败,默认的内存分配函数会直接抛出bad_alloc异常 std::set_new_handler(0); //operator new函数,只分配所要求的空间,而并不调用相关对象的构造函数 //当无法满足所要求分配的空间时,会调用new_handler,若new_handler为空指针 //直接抛出bad_alloc异常 T* temp = (T*)(::operator new((size_t)(size * sizeof(T)))); if (temp == 0) { cerr << "out of memory" << endl; exit(1); } return temp; } template<typename T> inline void _deallocate(T* buffer) { ::operator delete(buffer); } template<typename T1,typename T2> inline void _construct(T1* p, const T2& value) { //placement new //p为指向一块已分配内存的指针.T1为构造对象的类型 //value?? new(p)T1(value); } template<typename T> inline void _destroy(T* ptr) { ptr->~T(); } template<typename T> class Allocator { public: typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& constreference; typedef size_t size_type; typedef ptrdiff_t difference_type; //rebind allocator of type U template<typename U> struct rebind { typedef Allocator<U> other; }; //hint used for locality pointer allocate(size_type n, const void* hint = 0) { return _allocate((difference_type)n, pointer(0)); } void deallocate(pointer p, size_type n){ _deallocate(p); } void construct(pointer p, const T& value) { _construct(p, value); } void destroy(pointer p){ _destroy(p); } pointer address(reference x){ return (pointer)&x; } const_pointer const_address(reference x){ return (const_pointer)&x; } size_type max_size() const { return size_type(UINT_MAX / sizeof(T)); } }; } #endif
cpp文件如下:
#include "simpleSTL.h" #include <vector> #include <iostream> using namespace std; int main() { int ia[5] = { 0, 1, 2, 3, 4 }; unsigned int i; vector<int, JJ::Allocator<int>> iv(ia, ia + 5); for (i = 0; i < iv.size(); ++i) { cout << iv[i] << ' '; cout << endl; } return 0; }
再在namespace JJ中增加类增加新类Testint
class Testint { private: int a; public: Testint(int b) :a(b){} ~Testint() { std::cout << "Destructor called" << std::endl; } friend std::ostream& operator<<(std::ostream& os,const Testint& testint); }; std::ostream& operator<<(std::ostream& os,const Testint& testint) { os << testint.a; return os; }
修改下main函数后可以看到适配器也可以正常运行