“向量类模板和异常处理” 问题分析

今天做了一道向量类模板和异常处理题,这道题我一开始还是用之前的错误的思维方式去思考的,所以又与真正的方向渐行渐远。后来怎么也想不通,索性百度了下,看到了别人贴出来的代码,才终于明白了其中的意义。对上次未做完的一道题也有了新的启发。

**

题目描述

**

参考C++ vector类模板,设计实现自己的CVector向量类模板,完成下列基本功能: 构造、析构、size、push_back和下标访问,在通过下标访问越界时抛出异常。编写测试程序,利用该类模板完成一个解释器,它接受命令,执行相应操作。

**

输入描述

**

输入命令有5种 :int 整数 代表开始建立整数向量 (整数为向量初始大小);string 整数 代表开始建立string向量;push对象 代表在向量尾追加对象; put 下标 对象 代表需将对象放入向量下标处;fetch 下标 代表取并打印向量下标处对象;当下标越界时抛出异常并显示invalid index:下标;quit代表本队列处理结束。每个队列以int或string开始,以quit结束;所有命令均小写。

**

输出描述

**

每个向量从建立到结束输出占一行; 各输出对象前含一个空格。

**

样例输入

**

int 10 push 100 push 200 push 50 push 300 put 0 5 put 1 20 push 400 fetch 1 fetch 12 fetch -1 fetch 20 fetch 11 quit
string 10 push hello push some push apple push box put 1 zhang push 2 yes fetch 2 push hdu fetch 1 fetch 20 fetch 12 quit

**

样例输出

**

20 50 invalid index:-1 invalid index:20 200
zhang invalid index:20 apple

……

……

一开始我的确知道要用类模板创建CVector类,但是却以为是可以直接用vector相关函数去解决。其实是要自己来创建算法实现vector类的功能。并且前者还有一个问题就是创建的是CVector类而不是vector向量容器,所以根本没办法用vector的函数。(也是因为怕麻烦Orz)
……

……

看到了别人的代码之后我一边感叹于其巧妙,一边反省我的错误。
有以下几(好多)个点:

  1. 开始我把put 、fetch 都作为函数写出来了,但其实这并不必要。因为它要求的是字符串输入这个执行相关指令,而不是输入的即为函数名。(这样的好处就是简化了类。
  2. 刚刚改的时候突然发现它还重载了 “[ ]” 运算符。因为data[ ]是类里的私有成员,不能直接访问,而重载 “[ ]” 时直接返回了data[ ] ,于是只需要用对象名 [ ] 就能访问了!(对我来说好难想简直神仙
  3. 一开始我的类里只有 size (向量长度)这一个私有成员数据,发现它的还有 capacity (向量容器初始大小)和 T *data ,我一开始还觉得 capacity 并不必要,因为似乎 size 就可以满足了(开始我在 push_back 那里还写了 size++ 想要以此纪录 size 变化后的大小)。但当时我以为可以直接用 push_back() 函数,所以没有考虑 data[ ] 是需要扩充的(扩充对于我来说也是一个很大很大的难点)所以 capacity 就是用来和 size 进行比较然后作为扩充的条件!(其实 *data[ ] 我也很难想到创建动态数组这样的用法…
  4. 关于扩充。这个函数是供push_back 函数使用的,目的是扩充 data[ ] 并向后追加数据。方法是先创建一个新的动态数组 temp[ ] 准备取代原来的,然后把 data[ ] 用循环语句全部赋值给 temp[ ] ,释放data[ ] (释放的是之前所指的那部分,而不是这个指针),然后再用 “data=temp” ,就成功实现了转移!!(sky!) 最后 “capacity=newSize”,扩充就完成了。(注意每一步都是细节)
  5. 关于 push_back 函数,首先它要进行扩充(才能将数据放进去),比较 size 与 capacity,如果相等就扩充(而且设定为扩充为原来的两倍,节约力气。其实一开始想不通为什么直接两倍而不是一个一个扩,因为后面还要比较抛出异常啊,后来发现比较时用的是size 所以就没关系了)。还有一种情况是之前已经扩充了并且放入了一个数,这时还没满所以不需要再扩充了,直接把值赋给 data 相应位置。并且细节是 “data[size++]=n” 其实它的作用我在下面的解释已经可以表明了,这里还有一点就是数组的最大下标比容量少一,所以要从下标为 size 处赋值。
  6. 异常抛出的部分。它在 [ ] 重载的时候检测异常,对应与 fetch 功能,因为这部分需要打印数据,所以将二者结合在一起是再好不过了。
  7. 终于到了执行部分。因为需要定义两种类型的向量,所以用上了模板,但是这样的话 main 函数里是不是也要把只有一丝差别的两种执行过程分别写出来呢?不会用的我就只能复制粘贴int类型的代码然后稍微改改变成string类的了。但是,既然知道了有模板,为什么还要用这么麻烦的方式啊!果然,别人的代码里就大大简化了。 然鹅,我看不懂它函数模板里的参数(一开始我连这是模板都看不出来……)……不管怎样,现在终于看懂了。它使用的参数其实并无意义,因为函数里不需要用到主函数传的任何参数,但它需要一个参数来表示它是 int 类型还是 string 类型,怎么办呢?所以就定了其实并没有意义的参数,只起一个告知类型的作用,所以是多少不重要,只要是需要的类型,随便谁做参数都可以(!!我终于看懂了!)快要藕血了Orz

^
【插入在第5点】刚刚测试了一下 i++ 相关……
发现我真的C语言基础太弱了……好多概念都是含糊不清,等到要写复杂的程序时却总在一些细枝末节上纠结……啊,如果能重来我一定超级,非常认真地好好学C语言……(只能现在看情况去恶补了……枯

#include<iostream>
using namespace std;

int main(){
	int a[4]={0,1,2,3};
	int i=0,j;
	j=a[i++];
	cout<<i<<endl;
	cout<<j;
	return 0;
}

这里的 “j=a[i++]” 分为两步,一步是 j=a[i] (i=0) , 所以 j=0,然后是 i=i+1,i=1 。所以关键是 i++ 虽然是在一个表达式中,看似是给 j 赋值,但其实 i 也自增了1 。又由于++在后,所以后进行自增。(自己解释都觉得很羞愧……这么简单的问题还需要纠结。(并且还有些术语我也不确定讲得对不对,有时是知道那个意思但是词可能表达得不准确。我还得多多包涵下我自己TAT)

那么就这样吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值