RAII(Resource Acquisition Is Initialization): 资源分配即初始化,定义封装一个类,用来实现调用构造函数时就可完成资源的分配和初始化,在调用析构函数就可完成资源的清理,以实现对资源的初始化和清理。 智能指针: 用自动化或者说智能的指针来实现对动态内存的释放。 它是一个类,有类似指针的功能。 常见的智能指针有:auto_ptr/scoped_ptr/scoped_array/shared_ptr/shared_array,我们今天先讲以下三种。
类型萃取是一种常用的编程技巧,其目的是实现不同类型数据面对同一函数实现不同的操作,它与类封装的区别是,我们并不用知道我 们所调用的对象是什么类型,类型萃取是编译后知道类型,先实现,而类的封装则是先定义类型,后实现方法。在这里我们可以用模板的特化实现其编程思想。 我们以memcpy为例,当我们拷贝的是基本类型时,只用拷贝所传递指针上的数据,如果是string类型呢,我们则需要在堆上开辟空间,所传递的指针如 果被直接复制,则有可能(vs下的string类型的实现原理是若字符串不长则以数组保存,若字符串过长,则通过指针在堆上开辟空间进行保存)出现同一地 址,析构两次这样的常见错误。 我们知道,类型分为基本类型(POD),和自定义类型。基本类型指在C++ 中与C兼容的类型,可以按照 C 的方式处理。而自定义类型如我们今天实现的静态顺序表。
适配器: 将一个通用的容器转换为另外的容器,所谓的容器,指的是存放数据的器具,像我们知道的顺序表和链表都是容器Container。举个例子解释一下吧,我们的电压都是220v,而像充电线就起到转换到合适的电压的作用。而这里,我们的主角就是将通用的链表结构转换为来实现队列Queue这一数据结构,(意思就是,链表还可以去实现其他的数据结构)。 在线性表中,分为链表和顺序表,我们知道其中的差别: 链表:节点灵活,使得插入删除元素方便灵活,但是对于单链表若有节点指针_head、_tail,查找元素较为麻烦,需要遍历。 顺序表:开辟一块连续的内存空间,查找元素方便,通过指针或者下标来访问。插入或者删除元素呢,又较为复杂,插入时需要将后面的元素挨着挨着全部后移,删除元素后又需要将后面的元素全部前移。 针对队列Queue模型,我们知道它是尾插头删、先进先出的特点。因此我针对以上原因选用链表结构来实现队列Queue。可以参照下图:
容器适配器实现栈Stack的各种功能: 我们知道,顺序表的特点是:相对比于链表插入和删除数据方便,无需像链表一样遍历来访问。因此,我们用容器适配器选择顺序表的模型来实现栈的各种功能。
在cplusplus.com里,我们可以搜索list来查看库是如何实现双向链表的。当然,我们也可以在平时使用时包上头文件list来调用C++里的list库。在这里,我今天就不再赘述用C语言或者C++未引入模版这两种场景来向大家分享双向链表了,而是注重多类型都可以使用双向链表。也就是我们今天的主题:模版实现双向链表。 我主要实现了尾插、尾删、打印、去重、逆置等等一系列操作,而关于像Insert()、Erase()之类的操作我并没有在这里全部实现,一方面是因为之前我们反复实现过,如果你感兴趣的话,可以查看我之前的博客。另一方面,我出于较为低效不常见的原因。希望大家理解。 另外,需要说明的一点是,今天我使用的均是类内声明,类外定义的方式。
在C或C++里,我们已经学会了如何实现一个静态顺序表了,那为何还要引入模版类来实现静态顺序表呢?首先,我们看,在未引入模版前,我们在C++里是这样定义一个静态顺序表的:typedef int DataType; //此时我定义的是int型 class SeqList { &
实现基类(父类)以及派生类(子类),验证继承与转换--赋值兼容规则:子类对象可以赋值给父类对象(切割/切片)父类对象不能赋值给子类对象父类的指针/引用可以指向子类对象子类的指针/引用不能指向父类对象(可以通过强制类型转换完成)#include<iostream> using namespace std; class&
建立源文件List.cppinclude "List.h" int main() { Test(); system("pause"); return 0; }建立头文件List.h#ifndef __LISH_H_
Copyright © 2005-2024 51CTO.COM 版权所有 京ICP证060544号