您的位置:首页 > 编程语言 > C语言/C++

C++ primer 第五版13.39代码

2021-10-23 21:47 465 查看
class StrVec{
public:
StrVec();                           // 构造函数
StrVec(const StrVec&);              // 拷贝构造
StrVec &operator=(const StrVec&);   // 拷贝赋值构造
~StrVec();                          // 析构函数
void pushBack(const string &);                    // 添加元素
size_t size(){return initEndPtr-beginPtr;};                      // 获取构造的元素个数
size_t capacity(){return endPtr-beginPtr;};                  // 获取开辟内存空间大小
[[nodiscard]] string *begin() const{return beginPtr;};                    // 获取构造元素的首指针
[[nodiscard]] string *end() const{return initEndPtr;};                      // 获取构造元素的尾指针
private:
static pair<string*, string*> allocCopy(string*, string*);  // 拷贝操作
void free();  // 释放空间
void reAlloc(); // 重新开辟内存
static allocator<string> alloc;  // 用于分配对象
string *beginPtr;  // 开辟内存首指针
string *initEndPtr;   // 构造元素首指针
string *endPtr;     // 开辟内存尾指针
};

allocator<string> StrVec::alloc;  // 静态变量需要类外初始化
StrVec::StrVec(): beginPtr(nullptr), initEndPtr(nullptr), endPtr(nullptr) {}

pair<string *, string *> StrVec::allocCopy(string *b, string *e) {
auto data = alloc.allocate(e - b);  // 开辟内存
return {data, uninitialized_copy(b, e, data)};  // 拷贝元素
}

StrVec::StrVec(const StrVec &rhs) {
auto ptr = allocCopy(rhs.begin(), rhs.end());
beginPtr = ptr.first;
endPtr = initEndPtr = ptr.second;
}

StrVec &StrVec::operator=(const StrVec &rhs) {
if (this == &rhs) return *this;
auto ptr = allocCopy(rhs.begin(), rhs.end());  // 先开辟空间后释放
free();
beginPtr = ptr.first;
endPtr = initEndPtr = ptr.second;
return *this;
}

void StrVec::free() {
if (beginPtr){
for (auto ptr = initEndPtr; ptr != beginPtr ;)
alloc.destroy(--ptr);  // 析构元素
alloc.deallocate(beginPtr, capacity());  // 释放内存
}
}

StrVec::~StrVec() {
free();
}

void StrVec::pushBack(const string &str) {
if (size() == capacity()) reAlloc();  // 内存不足是重写分配内存
alloc.construct(initEndPtr++, str);
}

void StrVec::reAlloc() {
auto newCapacity = size()? 2*size(): 1;
auto newData = alloc.allocate(newCapacity);  // 分配新内存
auto dest = newData;
auto res = beginPtr;
for (auto i = 0; i < size(); ++i)
alloc.construct(dest++, move(*res++));  // 构造
free();  // 释放原内存
beginPtr = newData;  // 更新指针
initEndPtr = dest;
endPtr = newData + newCapacity;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: