当前位置:网站首页>StrVec类 移动拷贝
StrVec类 移动拷贝
2022-06-12 07:56:00 【jackniu123】
StrVec是对vector的仿写。string在内存中连续存放,当内存空间不足时,申请两倍的内存空间,并利用string的移动拷贝进行转移。
有哪些成员
class StrVec
{
public:
StrVec() : elements(nullptr), first_free(nullptr), cap(nullptr) {
}
StrVec(const StrVec&);
StrVec(StrVec&& s)noexcept;
StrVec& operator=(StrVec&& rhs);
StrVec& operator=(const StrVec&);
~StrVec();
void push_back(const string&);
size_t size() const {
return first_free - elements; }
size_t capacity() const {
return cap - elements; }
string* begin() const {
return elements; }
string* end() const {
return first_free; }
private:
static allocator<string> alloc;
string* elements;//首指针
string* first_free;//利用内存的尾后指针
string* cap;//数组尾后指针
void free(); //销毁元素并释放内存
void reallocate(); //获得更多内存并拷贝已有元素
//被添加元素的函数使用
void chk_n_alloc();
//工具函数,被拷贝构造函数、赋值运算符、析构函数使用
pair<string*, string*> alloc_n_copy(const string*, const string*);
};
逐一分析
数据成员
- 静态成员allocator:负责申请内存空间。allocator类的作用是把内存申请和对象初始化分开。STL常使用allocator类动态申请内存。allocate可视为malloc的封装, deallocate可视为free(不是new和delete), construct可视为手动调用构造函数,deallocate可视为手动调用析构函数。分配内存后即可认为StrVec类内部有一个动态数组。
string* p = new string[10];实际上做了两个工作:跟操作系统申请十个string大小的内存空间,然后对其执行默认初始化——即运行默认构造函数。而alloc.allocate(10)仅仅是申请内存空间,没有初始化的过程。
- 三个指针。elements, first_free, cap依次为首指针,尾后指针,内存空间最后一个位置的指针。
拷贝控制
- 默认构造:三个指针全设为空。
- 拷贝构造:先分配等大小的内存空间,然后利用unitialize_copy方法一次完成初始化。
- 移动构造:先分配等大小的内存空间,然后将三个指针设置为rhs的值。注意将rhs赋值为可析构的状态。
- 拷贝运算符:采用拷贝并复制方法确保异常安全。其余与拷贝构造相同。
- 移动拷贝运算符重载:采用先比较排除自赋值的方法,其余与移动构造相同。
- 析构函数:释放allocator的内存空间。
工具函数
- free:实际上就是析构函数。
- alloc_n_copy:拷贝构造的功能提取。返回首指针与尾后指针。
- chk_n_copy:判断内存空间是否更大。
- reallocate:当需要更大空间时调用此函数。先申请内存空间,再调用string的移动拷贝,这里不能使用unintial_copy。
代码
#include <iostream>
#include <algorithm>
#include <utility>
#include <memory>
#include <string>
using namespace std;
class StrVec
{
public:
StrVec() : elements(nullptr), first_free(nullptr), cap(nullptr) {
}
StrVec(const StrVec&);
StrVec(StrVec&& s)noexcept;
StrVec& operator=(StrVec&& rhs);
StrVec& operator=(const StrVec&);
~StrVec();
void push_back(const string&);
size_t size() const {
return first_free - elements; }
size_t capacity() const {
return cap - elements; }
string* begin() const {
return elements; }
string* end() const {
return first_free; }
private:
static allocator<string> alloc;
string* elements;//首指针
string* first_free;//利用内存的尾后指针
string* cap;//数组尾后指针
void free(); //销毁元素并释放内存
void reallocate(); //获得更多内存并拷贝已有元素
//被添加元素的函数使用
void chk_n_alloc();
//工具函数,被拷贝构造函数、赋值运算符、析构函数使用
pair<string*, string*> alloc_n_copy(const string*, const string*);
};
void StrVec::chk_n_alloc()
{
if (size() == capacity())
reallocate();
}
void StrVec::push_back(const string& s)
{
chk_n_alloc();
alloc.construct(first_free++, s);
}
pair<string*, string*> StrVec::alloc_n_copy(const string* b, const string* e)
{
//分配空间保存给定范围内的元素
auto data = alloc.allocate(e - b);
//初始化并返回一个pair
return {
data, uninitialized_copy(b, e, data) };
}
void StrVec::free()
{
if (elements)
{
for_each(elements, first_free, [this](string* rhs) {
this->alloc.destroy(rhs); });
// for (auto p = first_free; p != elements; )
// alloc.destroy(--p);
}
alloc.deallocate(elements, capacity());
}
StrVec::StrVec(const StrVec& s)
{
auto newdata = alloc_n_copy(s.begin(), s.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
StrVec::~StrVec()
{
free();
}
StrVec& StrVec::operator=(const StrVec& rhs)
{
auto data = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = data.first;
cap = first_free = data.second;
return *this;
}
void StrVec::reallocate()
{
auto newcapacity = size() ? 2 * size() : 1;
auto newdata = alloc.allocate(newcapacity);
auto dest = newdata;
auto elem = elements;
for (size_t i = 0; i != size(); i++)
{
alloc.construct(dest++, move(*elements++));
}
free();
elements = newdata;
first_free = dest;
cap = elements + newcapacity;
}
StrVec::StrVec(StrVec&& s)noexcept
:elements(s.elements), first_free(s.first_free), cap(s.cap)
{
s.cap = s.first_free = s.elements = nullptr;
}
StrVec& StrVec::operator=(StrVec&& rhs)
{
if (this != &rhs)
{
free();
elements = rhs.elements;
cap = rhs.cap;
first_free = rhs.first_free;
rhs.first_free = rhs.elements = rhs.cap = nullptr;
}
return *this;
}
int main()
{
}
边栏推荐
- Leetcode notes: biweekly contest 70
- Parameter estimation of Weibull distribution
- Utilize user tag data
- 2021.11.2 scientific research log
- Ten important properties of determinant
- The computer is connected to WiFi but can't connect to the Internet
- Dynamic simulation method of security class using Matlab based Matpower toolbox
- 2021.10.24-25 scientific research log
- Ecmascript6 interview questions
- 移动端、安卓、IOS兼容性面试题
猜你喜欢

Voice assistant - Qu - single entity recall

Servlet

Voice assistant - DM - distribution and sorting

谋新局、促发展,桂林绿色数字经济的头雁效应

Windows10 configuration database

The computer is connected to WiFi but can't connect to the Internet

Leverage contextual information

Improvement of hash function based on life game

MinGW offline installation package (free, fool)

『Three.js』辅助坐标轴
随机推荐
20220525 RCNN--->Faster RCNN
Mathematical knowledge - matrix - matrix / vector derivation
NaiveBayes function of R language e1071 package constructs naive Bayes model, predict function uses naive Bayes model to predict and reason test data, and table function constructs confusion matrix
Chapter 2 - cyber threats and attacks
20220524 deep learning technology points
Meter Reading Instrument(MRI) Remote Terminal Unit electric gas water
Logistic regression
Generalized semantic recognition based on semantic similarity
Voice assistant - Multi round conversation (process implementation)
Preliminary knowledge next New concepts such as isr/rsc/edge runtime/streaming in JS
CONDA reports an error when creating a virtual environment, and the problem is solved
Voice assistant - future trends
System service configuration service - detailed version
Support vector machine (SVM)
The Poisson regression model (posion) is constructed by GLM function of R language, and the poisgof function of epidisplay package is used to test the goodness of fit of the fitted Poisson regression
Pytorch installation (GPU) in Anaconda (step on pit + fill pit)
Dynamic simulation method of security class using Matlab based Matpower toolbox
Rich dad, poor dad Abstract
Improvement of hash function based on life game (continued 1)
Chapter 6 - identity authentication, Chapter 7 - access control