1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | void reverse(Node * T) { assert(T); //~ 表头非空 Node* p = T->next, *t; if(p) { //~ 将第一个结点,即未来的表尾next域置空 t = p->next; p->next = NULL; p = t; } while(p) { //~ 将余下结点依次插入表头 t = p->next; p->next = T->next; T->next = p; p = t; } } |
有一点需要注意的是,由于STL内的容器的析构函数都不是virtual的,所以,继承这些容器的类(或者模板类)不能用于多态!这也是不提倡继承STL容器的原因。
不过,由于上面的代码中mstack
继承vector的目的不是使用多态特性,仅仅是复用了vector的接口而已,且复用也仅仅是内部复用;
由于是私有继承,你无法调用父类vector的接口,子类与父类接口并不一致,在语法就不能用于多态;
综上所述,这样的继承并没有什么潜在的危险。
Linux Air
对其它所有航空公司都不满的员工决定离开他们自己的航空公司。他们开始自己建造飞机,机票柜台,以及自己铺设飞机跑道。他们只用很少的费用给你提供可打印的机票,但你完全可以自己下载下来打印机票。
当你登机的时候,会有人递给你一个座位,四个螺栓,一个扳手和一本“安装座位-HOWTO.html”手册。一但安装好了,可随意调整或更改的座位可能让你相当地舒服,从飞机离开到目的地,其几乎不会发生一个错误,而且,飞机过程中的飞行餐非常不错。你会想去告诉选乘别的航空公司的乘客你那完美的经历,但你所能得到的回答是,“乘座飞机还要必需要去安装自己的座位?”。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | template <class T> class Queue { public: Queue(int size = 30); ~Queue(); void EnQueue(T value); T DeQueue(); T GetFirst(); bool IsEmpty(); bool IsFull(); void ClearQueue(); private: T *queue; int front; int rare; int MaxSize; int CurLen; }; |
一个堆栈类模板,和用到此模板的一个表达式计算器。
输入四则运算表达式(可含括号),输出计算结果,暂未提供盛放运算和浮点数功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class Stack { public: Stack(int stack_size = 30); ~Stack(); void Push(T value); T Pop(); T Top(); bool IsEmpty(); bool IsFull(); void ClearStack(); private: int top; T* stack; int size; }; |
一种遍历算法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | int main() { string word; cin>>word; int len = word.length()-1; long psb = 1; for (int i = 0;i < len;i++) { psb *= 2; } int *flags = new int[len]; for (int i = 0;i < psb;i++) { int temp = i; for (int j = 0;j < len;j++) { flags[j] = temp%2; temp = temp/2; } if(i>0) { for (int j = 0;j < len;j++) { cout<<word[j]; if(flags[j] == 1)cout<<"-"; } cout<<word[word.length()-1]<<endl; } } } |
这里的内存会被正确释放吗?答案要分两方面来讨论。*pd对象本身的内存(4Byte)会不会被释放,就像上例中所说,我还是不知道。但(*pd)::pi所指向的内存肯定是打了水漂啦!因为delete看到的只是一个char*类型的pd,只会简单做一些处理(待高人讲解),而不会调用析构函数demo::~demo()。甚至有时候它会调用其他类的析构函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include <iostream> using namespace std; class demo { public: //~ 此处省略代码数行…… ~demo() { delete [] pi; } private: int * pi; }; class foo { public: ~foo(){cout<<"foo's collapsing..."<<endl; }; int main() { demo * pd = new demo; delete (foo*)pd; return 0; } |
foo童鞋真是可怜,让我们来了个借尸还魂,Orz,借刀杀人才对!
1 2 3 4 5 6 7 8 9 10 11 12 | template <class T> T Min(T x, T y) { return x < y ? x : y; } int main() { unsigned ui = 0; int a = Min(ui, 1); return 0; } |
这几行代码又有哪些错误呢?cl.exe提示说,error C2782: ‘T Min(T,T)’ : template parameter ‘T’ is ambiguous。在参数类型的确定上产生了不确定性,这是为什么呢?好吧,1会被解释成是int型的,但是我们平时不是经常把int直接传给unsigned类型的参数吗?可惜的是,此时的Min还不是一个函数,它只是一个模板而已,实例化之前尚不能完成参数的隐式转化(其实,我认为这只是编译器支持与否的问题)。同样,可以用显式特例化的方法来解决:
int a = Min
当然,还可以强制类型转换:
int a = Min(ui, (unsigned)1); 或者 int a = Min(
我能抽象出整个世界... 但是我不能抽象出你... 因为你在我心中是那么的具体... 所以我的世界并不完整... 我可以重载甚至覆盖这个世界里的任何一种方法... 但是我却不能重载对你的思念... 也许命中注定了 你在我的世界里永远的烙上了静态的属性... 而我不慎调用了爱你这个方法... 当我义无返顾的把自己作为参数传进这个方法时... 我才发现爱上你是一个死循环... 它不停的返回对你的思念压入我心里的堆栈... 在这无尽的黑夜中... 我的内存里已经再也装不下别人... 我不停的向系统申请空间... 但却捕获一个异常---我爱的人不爱我... 为了解决这个异常... 我愿意虚拟出最后一点内存... 把所有我能实现的方法地址压入堆栈... 并且在栈尾压入最后一个方法---将字符串"我爱你,你爱我吗?"传递给你... 如果返回值为真--我将用尽一生去爱你... 否则--我将释放掉所有系统资源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /* * pre存放先序序列, * in存放中序序列, * n为结点个数, * 返回二叉树根指针 */ BTree CreateBT(Type * pre, Type * in, int n) { if(n <= 0) return NULL; BTree bt = new BTNode; Type * p; int k; bt->data = *pre; for(p = in; p < in + n; ++p) if(*pre == *p) break; k = p - in; bt->lchild = CreateBT(pre+1, in, k); bt->rchild = CreateBT(pre+k+1, p+1, n-k-1); return bt; } |
