当前位置: 首页 > wzjs >正文

网站图片用什么做的区块链开发工程师要求

网站图片用什么做的,区块链开发工程师要求,上杭网站建设,软件开发流程图片目录 1.结构 2.构造函数 无参构造 指定参数构造 迭代器构造 初始化列表构造 3.拷贝构造 4.析构函数 5.遍历 重载【】 5.插入 扩容 尾插 指定位置插入 6.删除 尾删 指定位置删除 1.结构 vector是一个类似于数组一样的容器,里面可以放各种各样的元素…

目录

1.结构

2.构造函数

无参构造

指定参数构造

迭代器构造

初始化列表构造

3.拷贝构造

4.析构函数

5.遍历

重载【】

5.插入

扩容

尾插

指定位置插入

6.删除

尾删

指定位置删除


1.结构

vector是一个类似于数组一样的容器,里面可以放各种各样的元素。我们只需在其中储存空间的地址即可,所以包含三个私有元素,分别是_start_finish_end_of_storage。使用模板T可以使vector储存各种各样的元素。将元素指针类型typedef成迭代器。代码如下。

        template <class T>typedef T* iterator;    typedef const T* const_iterator;
private:iterator _start = nullptr;iterator _finish = nullptr;iterator _end_of_storage = nullptr;

2.构造函数

包含无参构造指定参数构造迭代器构造初始化列表构造

无参构造

不用传参,使用缺省参数或者初始化列表中的参数。

指定参数构造

第一个参数n表示空间大小,第二个参数const T& val = T()是一个缺省参数,当没有传递第二个参数的时候,会调用T的默认构造函数,用val来引用它。比如说T是int类型,那么val就是0的引用所以这里要加const,然后再用val去初始化剩余的空间

为什么要n有size_t和int两种类型呢?

如果只定义size_t,那么传参(6,5)的时候,编译器默认6是int类型,与size_t类型不符合,那么就会找更匹配的构造函数,这时候会找到迭代器构造,而此时就会出现非法的间接寻址(int类型的值无法解引用)编译错误。

如果只定义int,那么传递的参数指定是size_t类型,如(6u,5)(后缀加u表示unsign int类型),同样会产生相同的问题。所以两者都显示定义了。

迭代器构造

参数为迭代器,迭代器是与指针类似的东西,可以进行解引用,+,-等操作。

这里为什么不使用前面的迭代器iterator,而是要使用一个成员函数模板?前面的iterator只能表示vector容器的迭代器,当我们想用其他容器的迭代器来初始化vector的时候就不适用了,所以要定义一个新的函数模板。

其实我自己在学的时候还有一个疑问就是为什么std::list<double> iterator能初始化vevtor<int>?

一是本质上使用的是(*first)来初始化的,拿到的是double类型的元素,

二是这其中实际上涉及到了隐式类型转换将double转换成了int。

初始化列表构造

std::initializer_list<T>是C++11 标准类型,专门处理花括号 {} 初始化(如 {1, 2, 3},之后再遍历尾插。这种方法可以避免重复地push_back。

//无参
vector<int> v1;
//指定参数
vector<int> v2(6);
//迭代器构造
string s1("wit lzk");
vector<int> v3(s1.begin(), s1.end());
//花括号
vector<int> v4 = { 1,2,3,5 };
//构造函数vector(){}vector(size_t n, const T& val = T()){reserve(n);for (size_t i = 0; i < n; i++){push_back(val);}}vector(int n, const T& val = T()){reserve(n);for (int i = 0; i < n; i++){push_back(val);}}template <class InputIterator>vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);++first;}}vector(std::initializer_list<T> il){reserve(il.size());for (auto t& : il){push_back(t);}}

3.拷贝构造

旧版拷贝构造分为开空间,遍历,拷贝

//拷贝构造vector(const vector<T>& v){reserve(v.capacity());for (auto& t : v){push_back(t);}}

赋值本质上也复用了拷贝构造。比如说v2 = v1把v1赋值给v2,v1进行传值传参,调用拷贝构造函数,v1会生成一个临时副本拷贝给v,然后利用swap将v的值和v2交换,实现赋值操作。同时v是一个临时对象,在和v2进行交换后函数结束时就会将原空间析构。

        void swap(vector<T> v){std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_end_of_storage, v._end_of_storage);}vector<T>& operator=(vector<T> v){swap(v);return *this;}

4.析构函数

析构函数还是看构造函数构造了什么,析构函数就析构什么。

/析构函数~vector(){delete[] _start;_start = _finish = _end_of_storage = nullptr;}

5.遍历

得到对象空间大小,和实际数据个数。

size_t size() const
{return _finish - _start;
}
size_t capacity() const
{return _end_of_storage - _start;
}

重载【】

T operator[](size_t n)
{assert(n < size());return _start[n];
}
vector<int> v1 = { 1,2,3,4 };
//[]遍历
for (size_t t = 0; t < v1.size(); t++)
{cout << v1[t] << " ";
}
cout << endl;
//范围for遍历
for (auto ch : v1)
{cout << ch << " ";
}
cout << endl;

5.插入

插入前需要判断空间是否足够,不够需要扩容。拷贝数据到新空间时,不能使用memcpy,如果是内置类型还好,如果是自定义类型,浅拷贝将会导致空间析构两次。所以直接暴力拷贝数据。因为是异地扩容,所以拷贝完毕要重新给类成员变量赋值。

扩容

//扩容
void reserve(size_t n)
{//扩容是改变(_end_of_storage-start)的值/*if (n <= _end_of_storage - _start){_finish = _start + n;}*/if(n > capacity()){size_t pre_size = size();T* tmp = new T[n];//_start不能为空if (_start){//使用memcpy为浅拷贝,资源会被析构两次//memcpy(tmp, _start, sizeof(_start));for (size_t i = 0; i < size(); i++){tmp[i] = _start[i];}//数据拷贝完要把旧空间删除delete[] _start;}_start = tmp;_finish = _start + pre_size;_end_of_storage = _start + n;}
}

尾插

//尾插
void push_back(const T& v)		 
{size_t len = _finish - _start;//写法太冗余//if (_finish < _end_of_storage)//{//	_start[len] = v;//}//else {//	//空间不够扩容//	reserve(capacity() == 0 ? 4 : 2 * capacity());//	_start[len] = v;//}//_finish++;//相等就扩容if (_finish == _end_of_storage){reserve(capacity() == 0 ? 4 : 2 * capacity());}//无论满没满都要进行这两步(*_finish) = v;_finish++;
}

指定位置插入

这里需要注意迭代器失效的问题,异地扩容后_start被改变,pos也就失效了。所以要先记录pos到_start的距离,扩容后重新赋值。

//指定位置插入
iterator insert(iterator pos, const T& x)
{assert(pos >= _start);assert(pos <= _finish);if (_finish == _end_of_storage){size_t len = pos - _start;reserve(capacity() == 0 ? 4 : 2 * capacity());//扩容完后的_start会改变//原来的pos会失效(迭代器失效了)pos = _start + len;}//移动数据iterator it = _finish;while (it >= pos){*it = *(it - 1);it--;}*pos = x;_finish++;return pos;
}

6.删除

尾删

改变一下_finish的位置即可。


//尾删
void pop_back()
{assert(_finish > _start);_finish--;}

指定位置删除

那么在这个地方vs实现的vector会出现迭代器失效的问题。vs会认为erase一次后it就失效了,所以必须在使用erase之后,重新给it赋值。 当然自己实现的vector中不会出现这个问题。

vector<int> v = { 1,1,2,3,3,4,5,6,7,8,9,9 };
for (auto ch : v)
{cout << ch << " ";
}
cout << endl;
//删除所有奇数
vector<int>::iterator it = v.begin();
while (it != v.end())
{if (*it % 2 == 1){//重新赋值it = v.erase(it);}else {it++;}
}
for (auto ch : v)
{cout << ch << " ";
}
cout << endl;
iterator erase(iterator pos)
{assert(pos >= _start);assert(pos <= _finish);iterator it = pos;while (it < _finish){*it = *(it + 1);it++;}_finish--;return pos;
}

"Happy Coding! 🚀" 

http://www.dtcms.com/wzjs/810626.html

相关文章:

  • 个人备案 网站名淄博网站建设公司三农
  • 高平网站优化公司地方门户网站系统有哪些
  • 长春网站建设模板样式做视频找素材的网站有哪些
  • 网站建设费用报价网站建设公司华网天下北京
  • idea做网站登录厦门网站建设工程
  • 山西通州集团网站建设国际进出口贸易网站
  • 网站建设 数据归属微信平台可以做微网站吗
  • 大连投诉网站网页升级访问最新区域每天自动更新
  • 无忧网站优化淘宝店招图片大全免费
  • 做网站编辑需要看什么书全网营销的四大优势
  • 集团网站建设报价企业局域网做网站屏蔽
  • 信阳网站建设找汉狮百度小说风云榜排名
  • 网站建设 域名 数据库济南品牌网站建设定制
  • 海城建设网站wordpress国外vps
  • 中国优秀设计网站有哪些福田企业网站建设
  • 芜湖手机网站开发什么是平面设计 都包括哪些内容
  • 个人开发的软件能卖吗网站优化和推广
  • 河南省住房和城乡建设局网站长沙网络公司营销推广
  • 铜仁网站网站建设青海网站建设的企业
  • 云畅网站建设国内最大ae模板下载网站
  • 门户网站 建设企业网站备案
  • wordpress 双语站点拓者设计吧手机版
  • 网站开发的前端与后端如何加快百度收录网站
  • 南通门户网站世界杯直播入口官网
  • 掼蛋网站建设项目管理工具
  • 永州建设公司网站wordpress的用户名密码
  • 建立网站需要多少钱怎么样国内最大的搜索引擎
  • 广州营销型网站建设团队抚顺市+网站建设
  • 北京+网站建设中国科技成就作文800字
  • 网页给别人做的 网站后续收费杭州搜索推广公司