12.2.1new和数组
| Int *pia = new int[get_size()]; Typedef int art[42]; Int *p = new art; Int *Pia = new int[10]; Int *pia2=new int[10](); String *psa = new string[10]; String *psa2 = new string[10](); Int *pia3 = new int[10]{0,1,2,3,4,5,6,7,8,9}; String *psa3 = new string[10]{“a”,”an”}; Int *p = new int[0]; Delete[] p; Unique_ptr<int[]> up(new int[10]; Up.release();//delete [] Up[i] = I; Shared_ptr<int> sp(new int[10],[](int *p){delete[] p;}); Sp.reset(); *(sp.get()+i_=I; |
1. 动态数组 1)一次为很多对象分配内存功能 2)两种分配一个对象数组的方法,new和allocator 3)new将分配和初始化绑定在一起,没用到的内存,但是也分配了内存并且有初始值 就浪费了。allocator可将分配和初始化分离,这样更灵活 4)最好使用vector标准库容器,而不是动态分配数组,容器的类可以使用默认版本的拷贝、赋值和析构操作。分配动态数组的类必须定义自己版本的操作,在拷贝、复制以及销毁对象时管理所关联的内存。 5)分配动态数组的类必须定义自己版本的操作,在拷贝 复制以及销毁对象时管理所关联的内存 2. New和数组 1)在类型名之后跟一对方括号,在其中指明要分配的对象的数目。分配成功返回指向第一个对象的指针 2)大小必须是整形不必是常量,也可以用一个别名。 3. 分配一个数组会得到一个元素类型的指针 1)叫 动态数组,并不是真的是数组类型的对象,而是得到一个数组元素类型的指针。即使使用类型别名,也不会得到数组类型的对象 2)因为不是数组类型,所以不能使用begin(),也不能使用for处理动态数组中的元素 4. 初始化状态分配对象的数组 1)new分配的对象,都是默认初始化,可以对数组中的元素进行值初始化,跟上空括号。 2)可以提供一个元素初始化器的花括号列表 3)初始化可以混合,前4个初始化器初始,剩下的值初始化 4)若初始化数目小于元素数目,剩余元素将进行值初始化。 若初始化数目大于元素数目,报错,不会分配任何内存,抛出bad_array_length异常 5)不能在值初始化的括号中给出初始化器,意味着不能用auto分配数组 5. 动态分配一个空数组是合法的 1)动态分配一个空数组是合法的并且可以使用下标为0的元素,但不能解引用 2)就像尾后指针一样,可以进行比较操作,可加减0; 3)不能定义长度为0的数组,但可以一个动态分配一个空数组 6. 释放动态数组 1)只删除p对象是错误的 未定义的 报错,猜想:只删除第一个元素吧? 或者销毁第一个元素并且不指向数组了所以会访问不到,但是数组依然存在除了第一个位置的 2)需要加上方括号对,按逆序销毁 3)空括号是必须的。意味p只是指向一个对象数组的首元素,而不是一个类型为arrT的的单一对象 Note:单delete p可能不发出警告,但在运行时会异常 7. 只能指针和动态数组 1)Unique可以管理new分配的数组的unique_ptr版本 2)并且可以用下标访问数组中的元素 3)Unique销毁自动调用delete[] 4)不直接支持管理动态数组,若想需要自定义删除器,使用lambda作为删除器,使用delete[]释放数组。 若没有删除器,则默认使用delete删除对象,会未定义的 5)不提供下标访问数组的元素,而且只能指针类型不支持算术运算。需用get先获取内置指针再操作 |
12.2allocator类
| Allocator<stirng> alloc; Auto const p = alloc.allocate(n); Alloc.construct(q++); Alloc.construct(q++,”hi”) Alloc.construct(q++,10,’c’) while (q1 != p1) { alloc1.destroy(--q1);// 释放构造了的string,逆序,只能对构造了的进行destory } alloc1.deallocate(p1, 3);//归还内存 allocator<int> all2; auto p2 = all2.allocate(ve.size() * 2); auto q2 = uninitialized_copy(ve.begin(), ve.end(), p2);//目的位置,返回的是最后一个位置 uninitialized_fill_n(q2, ve.size(), 42);// |
1. allocator类 1)new 将内存分配和对象构造组合绑定了一起,delete将对象析构和内存释放组合了一起 2)希望内存分配和对象构造分离可以使用allocator类 3)列子,string被赋值了两次,一次默认初始化,一次赋值时, 有可能没有用到内存也被附上了初始值,因为默认初始化, 更重要的,没有默认构造函数的类无法动态分配数组。 2. allocator类2 1)头文件memory中是一个模板需指定可以分配的对象类型 2)分配的内存是原始的 未构造的 3)根据对象类型来确定恰当的内存大小和对齐位置。分配后返回第一个内存的地址吧 3. allocator分配未构造的内存 alloc1.construct(q1++); alloc1.construct(q1++, 10, 'c'); alloc1.construct(q1++, "hi"); note:用construct构造对象。若没有构造的对象的内存使用了 未定义的 note:只能对真正构造了的元素进行destroy操作 destroy了元素后,可以将内存归还系统。Deallocate完成。大小参数需一样,不能大于初始化的大小 4. 拷贝和填充未初始化内存的算法 1)两个伴随算法,拷贝和填充,定义在memory中 2)可以用迭代器指定位置,或者迭代器指向的内存地址+n的形式 3)Copy返回最后一个构造的元素之后的位置,fill_n不返回 |