仿照Vector实现MyVector,最主要实现二倍扩容
- #include
-
- using namespace std;
-
- template <typename T>
- class MyVector
- {
- private:
- T *data;
- size_t size;
- size_t V_capacity;
- public:
- //无参构造
- MyVector():data(nullptr),size(0),V_capacity(0) {
- //cout<<"MyVector::无参构造"<
- }
- //有参构造
- MyVector(int count,T val){
- size = count;
- V_capacity = count;
- data = new T[count];
- for(int i = 0;i < count;i++){
- data[i] = val;
- }
- //cout<<"MyVector::有参构造"<
- }
- //析构函数
- ~MyVector(){
- delete [] data;
- data = nullptr;
- //cout<<"MyVector::析构函数"<
- }
- // 定义迭代器类
- class MyIterator {
- private:
- T* ptr;
- public:
- //有参构造
- MyIterator(T* p):ptr(p){
- //cout<<"MyIterator::有参构造"<
- }
- // *重载
- T& operator*()const {
- return *ptr;
- }
- // 前置++重载
- MyIterator& operator++() {
- ++ptr;
- return *this;
- }
- // 后置++重载
- MyIterator operator++(int) {
- MyIterator temp = *this;
- ++ptr;
- return temp;
- }
- // 前置--重载
- MyIterator& operator--() {
- --ptr;
- return *this;
- }
- // 后置--重载
- MyIterator operator--(int) {
- MyIterator temp = *this;
- --ptr;
- return temp;
- }
- // ==重载
- bool operator==(const MyIterator& other) const {
- return ptr == other.ptr;
- }
- // !=重载
- bool operator!=(const MyIterator& other) const {
- return ptr != other.ptr;
- }
- };
- //begin 函数 返回第一个元素的迭代器
- MyIterator begin() {
- return MyIterator(data);
- }
- //end 函数 返回最末元素的迭代器(注:实指向最末元素的下一个位置)
- MyIterator end() {
- return MyIterator(data + size);
- }
- //assign 函数 对MyVector中的元素赋值
- void assign(size_t num, const T &val ){
- for(int i = 0;i < num;i++){
- data[i] = val;
- }
- cout<<"assign 函数"<
- }
- //at 函数 返回指定位置的元素
- T at(int pos){
- if(pos < 0 || pos >= size){
- throw int(1); //抛出异常
- }
- return data[pos];
- }
- //back 函数 返回最末一个元素
- T& back(){
- return data[size-1];
- }
- //capacity 函数 返回vector所能容纳的元素数量
- size_t capacity(){
- return V_capacity;
- }
- //clear 函数 清空所有元素
- void clear(){
- size = 0;
- }
- //empty 函数 判空
- bool empty(){
- return size == 0;
- }
- //front 函数 返回第一个元素
- T& front(){
- return data[0];
- }
- //pop_back 函数 移除最后一个元素
- void pop_back(){
- if(empty()){
- throw int(2); //抛出异常
- }
- size--;
- }
- //push_back 函数 在MyVector最后添加一个元素
- void push_back(const T& value) {
- if (size == V_capacity) {
- // 扩容逻辑
- size_t newCapacity = (V_capacity == 0)?1:V_capacity * 2;
- T* newData = new T[newCapacity];
- for(int i = 0;i < static_cast<int>(size);i++){
- newData[i] = data[i];
- }
- delete[] data;
- data = newData;
- V_capacity = newCapacity;
- }
- data[size++] = value;
- }
- //size 函数 返回Vector元素数量的大小
- size_t get_size(){
- return size;
- }
- };
-
- int main()
- {
- MyVector<int> V1(5,2);
- cout<<"V1的第一个元素 = "<
front()< - cout<<"V1的最末一个元素 = "<
back()< - cout<<"V1的capacity = "<
capacity()< - cout<
- cout<<"********************************************************"<
- cout<
-
- V1.push_back(8);
- V1.push_back(5);
- V1.push_back(7);
- V1.push_back(6);
- cout<<"V1的第一个元素 = "<
front()< - cout<<"V1的最末一个元素 = "<
back()< - cout<<"V1的capacity = "<
capacity()< - cout<<"V1的size = "<
get_size()< - cout<
- cout<<"********************************************************"<
- cout<
-
- int *p = NULL;
- MyVector<int>::MyIterator q(p);
- cout<<"当前容器内的元素:";
- for(q = V1.begin();q != V1.end();q++){
- cout<< *q <<"\t";
- }
- cout<
- cout<
- cout<<"********************************************************"<
- cout<
-
- V1.pop_back();
- cout<<"V1的最末一个元素 = "<
back()< - V1.pop_back();
- cout<<"V1的最末一个元素 = "<
back()< - V1.pop_back();
- cout<<"V1的最末一个元素 = "<
back()< - cout<<"V1的size = "<
get_size()< - cout<
- cout<<"********************************************************"<
- cout<
-
- V1.clear();
- cout<<"V1的size = "<
get_size()< -
- return 0;
- }
效果图:

一、异常处理
【1】异常概念
C++中的异常指的是在程序运行过程中出现的问题,没有任何语法错误,存在逻辑问题
【2】异常处理
- throw ----->抛出异常,抛出异常一定在异常发生之前
- try ····catch ----->捕获异常并进行异常处理
总结:
- 抛出异常一定在发生异常之前
- try···catch中可以存放所有可能发生异常的代码,只要有一条语句抛出异常,try后面的语句都不会执行
- 异常可以只有数据类型,也可以及有数据类型也有值
- catch可以通过数据类型,获取到异常的结果并使用if进行判断,如果每种异常抛出的都是不同的数据类型,catch中就无需定义变量
- 如果同种数据类型的异常有多个值,要依次根据值来判断异常的情况
- throw抛出异常往往被调函数的位置,try···catch往往在主调函数内处理异常
- #include
- using namespace std;
-
- void fun(int a,int b)
- {
- //throw 数据类型(值)
- //数据类型:指定抛出异常的类型,便于接收
- //值:针对不同的异常情况,给出不同的值,处理异常时使用
-
- //在执行语句之前先对可能发生异常的位置进行判断
- if(b==0)
- {
- throw double(1);
- }
- if(b==3)
- {
- //函数内抛出了两个double类型的异常,分别返回不同的值
- throw int(2);
- }
- if(b==2)
- {
- throw double(2);
- }
-
- cout << a/b << endl;
- }
-
-
- //处理异常一般在主函数内
- //try···catch处理异常
- int main()
- {
- //tyr尝试接收异常,try内可以放多条语句,
- //有一条语句抛出异常后,后面都不会执行
- try
- {
- //try去接收所有可能的异常
- fun(4,2);
- fun(2,1);
- fun(3,3);
-
- }
- //由于函数中,只有一个double类型的异常,所以可以直接对异常的类型进行判断
- catch (double a) //如果double后面加变量名,变量会获取到异常的结果
- {
- if(a==1)
- cout << "除数为0" << endl;
- if(a==2)
- cout << "除数为2是一个测试" << endl;
- }
- catch (int)
- {
- cout << "除数为3是一个测试" << endl;
- }
- fun(3,1);
-
-
- cout << "1" << endl;
- }
-
二、using的第三种用法
- #include
-
- //using namespace std;
- using std::string;
- class A
- {
- public:
- string name;
- };
- class B:public A
- {
- protected:
- using A::name;
- };
- namespace P {
- string n1;
- }
-
- //给命名空间重命名
- //namespace 新的名字 = 旧的名字
- //新名字和旧名字都能用
- namespace O = P;
- int main()
- {
- using std::cout;
- using std::endl;
-
- typedef int a; //后面可以直接使用a定义int类型的变量
- //C++11支持的
- using INT = int; //后面可以直接使用INT定义int类型的变量
- INT num1 = 100;
- cout << num1 << endl;
- P::n1 = "helo";
- O::n1 = "hi";
- cout << O::n1 << endl;
-
- return 0;
- }
三、类型转换
【1】隐式强转
以及和C中一致的显式强转
- #include
- using namespace std;
-
- int main()
- {
- float num1 = 2.3;
- int num2 = num1; //发生了隐式的强制类型转换
-
- //C中的显式强制类型转换
- double num3 = (double)num2;
- cout << num2 << endl;
- return 0;
- }
【2】C++中支持的强制类型转换
- const_cast,取消常属性,取消常量指针的属性
- static_cast,和平时使用时发生强转用法一致,几乎支持所有类型间的强转
- dynamic_cast,发生在父子类指针间的转换,如果转换失败,会返回空地址
- reinterpret_cast,给类型重新赋值,不常用,不会检查数据类型匹配问题
- #include
- using namespace std;
-
- class A
- {
- string name;
- public:
- virtual void show()
- {
- cout << name << endl;
- }
- };
-
- class B:public A
- {
- mutable int age;
- public:
- void fun()const
- {
- age = 90;
- }
- void show()
- {
- cout << &age << endl;
- }
- };
-
- int main()
- {
- //定义了一个常量num1
- const int num1 = 90;
- int *p; //定义了一个指针变量
- p = const_cast<int *>(&num1); //使用const_cast让指针指向const修饰的变量的地址
- *p = 12;
- cout << *p << endl;
- //mutable关键也可以取消常属性
-
- //static_cast适用于几乎所有的强制类型转换
- char var = 'a';
- int num2;
- //int num2 = (int)var;
- num2 = static_cast<int>(var);
- cout << num2 << endl;
-
- A* p1 = new B; //父类指针指向子类的空间
- A* p2 = new A; //父类指针指向父类的空间
- //B* p3 = static_cast(p2); p2指向父类的空间,但是static_cast可以强转成功
- B* p3 = dynamic_cast(p2);
- //使用了dynamic_cast,可以实现多态情况下,可以实现父子类指针的转换
- //如果父类指针没有指向子类的空间,返回值为0
- cout << "父类指针指向父类的空间" << p2 << endl;
- cout << "子类的指针" << p3 << endl;
- B* p4 = reinterpret_cast(p2);
- cout << "父类指针指向父类的空间" << p2 << endl;
- cout << "子类的指针" << p4 << endl;
-
- char *str = "hello";
- int a = reinterpret_cast<int>(str);
- cout << a << endl;
- //p3->show();
-
- return 0;
- }
四、lambda表达式
应用场合:
想要使用匿名的、临时的函数,并且还需要获取外部变量时
- lambda(λ)表达式,是C++11支持的
- lambda表达式,用于实现轻量级的匿名函数
- 定义:[]()mutable->返回值{函数体}; --->结果一般使用auto接收
- [捕获列表](参数列表)mutable->返回值{函数体};
- 1、[=]:对所有变量按值捕获
- [&]:对所有变量按引用捕获
- [a,b]:对a和b按值捕获
- [&a,&b]:对a和b按引用捕获
- //[=,&a]:对除a外的变量值捕获,a按引用捕获
- //[&,a]:对除a外的变量按引用捕获,a按值捕获
-
- 2、参数列表:和普通函数的参数一致,就是传参数到函数中
- 3、mutable可以写也可以不写:
- 如果不写mutable,在lambda表达式中不能修改按值捕获的变量的值,按引用捕获的不受影响
- 4、lambda实现的匿名函数的返回值
- 5、函数体就是匿名函数的实现
- #include
- using namespace std;
-
- int main()
- {
- int a = 90,b = 7,c,d,e;
- cout << "a=" << a << endl;
- cout << "b=" << b << endl;
- cout << "--------------------" << endl;
- //使用lambda表达式,实现主函数内变量值的交换
- //[=]:对所有变量按值捕获
- //[&]:对所有变量按引用捕获
- //[a,b]:对a和b按值捕获
- //[&a,&b]:对a和b按引用捕获
- //[=,&a]:对除a外的变量值捕获,a按引用捕获
- //[&,a]:对除a外的变量按引用捕获,a按值捕获
-
- //lambda表示式,使用auto类型获取
- auto fun = [&,a]()mutable->void{ int temp;
- temp = a;
- a = b;
- b = temp;};
- fun();
- //使用lambda实现求最大值
- auto max = [=]()->int{ if(a>b)
- return a;
- else
- return b; };
- cout << max() << endl;
- return 0;
- }
五、STL标准模板库
C++ Standard Template Library
C++ 标准模板库(STL)
C++ STL (Standard Template Library标准模板库) 是通用类模板和算法的集合,它提供给程序员一些标准的数据结构的实现如 queues(队列), lists(链表), 和 stacks(栈)等.
C++ STL 提供给程序员以下三类数据结构的实现:
- 顺序结构
- C++ Vectors
- C++ Lists
- C++ Double-Ended Queues
- 容器适配器
- C++ Stacks
- C++ Queues
- C++ Priority Queues
- 联合容器
- C++ Bitsets
- C++ Maps
- C++ Multimaps
- C++ Sets
- C++ Multisets
【1】Vector
Vector的底层实现,就是线性表
Vectors 包含着一系列连续存储的元素,其行为和数组类似。访问Vector中的任意元素或从末尾添加元素都可以在常量级时间复杂度内完成,而查找特定值的元素所处的位置或是在Vector中插入元素则是线性时间复杂度。
需要手动导入头文件#include
- 1、求vetcor容器的大小:
- size_type capacity();
- capacity() 函数 返回当前vector在重新进行内存分配以前所能容纳的元素数量.
- 2、添加元素
- void push_back( const TYPE &val );
- push_back()添加值为val的元素到当前vector末尾
- 3、求容器的真实大小
- size_type size();
- size() 函数返回当前vector所容纳元素的数目
- 4、给容器中的元素赋值
- void assign( size_type num, const TYPE &val );
- 赋num个值为val的元素到vector中.这个函数将会清除掉为vector赋值以前的内容.
- 5、访问容器中的元素
- TYPE at( size_type loc );
- at() 函数 返回当前Vector指定位置loc的元素的引用. at() 函数 比 [] 运算符更加安全, 因为它不会让你去访问到Vector内越界的元素.
- 6、清空容器中的元素
- void clear();
- clear()函数删除当前vector中的所有元素.
- 7、判空函数
- bool empty();
- 如果当前vector没有容纳任何元素,则empty()函数返回true,否则返回false.例如,以下代码清空一个vector,并按照逆序显示所有的元素:
- 8、返回起始位置的引用
- TYPE front();
- front()函数返回当前vector起始元素的引用
- 9、返回最后一个位置的引用
- TYPE back();
- back() 函数返回当前vector最末一个元素的引用.
- 10、返回起始元素的迭代器
- iterator begin();
- begin()函数返回一个指向当前vector起始元素的迭代器.
- 11、返回末尾下一个位置的迭代器
- iterator end();
- end() 函数返回一个指向当前vector末尾元素的下一位置的迭代器.
- 注意,如果你要访问末尾元素,需要先将此迭代器自减1.
- 12、指定位置的插入,由于没有提供返回指定位置迭代器,需要在第一个元素的迭代器上运算
- iterator insert( iterator loc, const TYPE &val );
- 在指定位置loc前插入值为val的元素,返回指向这个元素的迭代器,
- 13、移除最后一个元素
- void pop_back();
- pop_back()函数删除当前vector最末的一个元素,
- 14、构造函数
- vector( input_iterator start, input_iterator end );
- 迭代器(start)和迭代器(end) - 构造一个初始值为[start,end)区间元素的Vector(注:半开区间).
【2】List
list的底层实现是一个双向链表
主要功能
- 1、头插
- void push_front( const TYPE &val );
- push_front()函数将val连接到链表的头部。
- 2、最大容量
- size_type max_size();
- max_size()函数返回链表能够储存的元素数目
- 3、元素个数
- size_type size();
- size()函数返回list中元素的数量。
- 4、排序
- void sort();
- 给链表中的元素排序,默认是升序
- 5、判空
- bool empty();
- empty()函数返回真(true)如果链表为空,否则返回假。
-
相关阅读:
你了解PMP考试新考纲的内容吗?
Django笔记三十四之分页操作
微服务概述
RNA-seq——四、根据序列比对结果筛选差异基因
WebView输入框软键盘遮挡问题(沉浸状态栏和adjustResize的冲突)
氧化锌纳米线 Zinc oxide nanowires
电脑可以模拟人脑吗
ai实景直播矩阵式引流---技术开发搭建(剪辑、矩阵、直播)
HTML5和CSS3二接口
【cesium】3D Tileset 模型加载并与模型树关联
-
原文地址:https://blog.csdn.net/weixin_54147737/article/details/132890268