学习动态内存管理确实很累,看+写 花了很长的时间。写这两个类使我对vector、string的内部实现、动态分配的方法有了更深的理解。更重要的是,随着写的类越来越多,我慢慢地体会到了:写一个类,构造其结构是十分重要的。哪些是public,哪些是private,哪些函数应该作为成员函数,哪些函数应该作为友元函数,而哪些代码应该写成一个函数,其作为函数时参数、返回值的确定又应当考虑哪些……诸如此类,这些都是应该纳入考量的,但对现在的我来说也是很微妙的,书上的代码理所当然就这样做了,我自己写却又难以下手,学习的路仍然漫长。另一个需要注意的就是,写一个类,不应该拿到闷头就写,而应思考一下它所要的功能以及如何去实现,必要的话可以写下过程,或许这样更为高效吧。
StrVec类:
写这个类有两个地方运行遇到了问题。记录如下:
1.、默认形参在函数声明出现后,函数定义处则不允许再写出默认形参
2、静态成员std::allocator<std::string > alloc在类内声明后,必须类外定义
#ifndef STRVECTOR
#define STRVECTOR
#include<string>
#include<memory>
#include<utility>
#include<algorithm>
class StrVec
{
public:
//构造函数+拷贝控制成员
StrVec() :elements(nullptr), first_free(nullptr), cap(nullptr) {}
StrVec(std::initializer_list<std::string> str_vec); //由于str_vec.begin()是const stirng*
StrVec(const StrVec&); //不能直接转换为string* 需要分配空间 利用alloc_n_copy转换
StrVec& operator=(const StrVec&);
~StrVec();
//类似vector的成员函数
void pushback(const std::string&);
void reverse(size_t);
void resize(size_t, const std::string &str = std::string(""));
size_t size() const { return first_free - elements; }
size_t capacity() const { return cap - elements; }
//迭代器
std::string* begin() const { return elements; }
std::string* end() const { return first_free; }
private:
static std::allocator<std::string> alloc;
//工具函数
void chk_n_alloc() { if (size() == capacity()) reallocate(); }
std::pair<std::string*, std::string*> alloc_n_copy(const std::string*, const std::string*);
void free();
void alloc_n_move(size_t);
void reallocate();
//私有属性
std::string* elements;
std::string* first_free;
std::string* cap;
};
std::allocator<std::string> StrVec::alloc; //不要忘了类外定义!
void StrVec::free()
{
if (elements)
{
/*for (auto i = first_free; i != elements;)
alloc.destroy(--i);*/
std::for_each(elements, first_free, //this is better since no worry about t