作者:小 琛
欢迎转载,请标明出处。
C语言面对数据类型不同时候的瑕疵
C++语言的诞生是基于C语言的,很多C++的内容都是用于解决C语言的不足。在使用C进行编程的时候,常常会有以下情况
1、某函数是为了实现一个功能的,但参数类型有很多种
例:交换函数。该函数为了实现两个值的交换,但实际情况中数据的类型多种多样,为了保证程序不会报错和警告,C的解决办法就只能每个都写一份。这就会导致代码非常的繁杂!
void swap_int(int* a, int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void swap_float(float* a, float* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void swap_char(char* a, char* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
//...还有很多类型,代码繁杂
2、顺序表的实现
在实现顺序表的时候,C语言首先是将数据和方法(函数)分开,由于没有封装性数据会被随意更改。其次最重要的就是每个顺序表所存放的数据类型被固定话,当需要储存另一种类型的数据的时候,即要重新写一份,非常不方便。
typedef int Datetype;//固定的数据类型
typedef struct SeqList
{
Datetype* _a;
size_t capacity;
size_t size;
}SeqList;
泛型编程的引入
如果在C++中,存在这样一个模具,通过给这个模具中填充不同材料(类型),来获得不同材料的铸件(生成具体类型的代码)。
泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。
函数模板
1、函数模板的使用
格式:template < class [name]>
namespace Function
{
template <class T>
void swap(T& a, T& b)
{
T tmp = a;
a = b;
b = a;
}
}
2、模板的实际原理
函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器。
3、模板使用时的一些特殊情况
例子:如果我们在使用交换函数的时候,想让一个int类型和一个float类型交换,此时如果直接将这两个作为参数,会导致错误。
引入概念:显式实例化,在使用的时候加以类型显示的设定,如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错。
int main(void)
{
int a = 10;
double b = 20.0;
// 显式实例化
Add<int>(a, b);
return 0; }
类模板
为解决开头提出的问题,引入类模板
例子:顺序表的实现
首先区别于C的写法,将数据和函数进行了封装,更好的面向对象。其次使用了模板,以解决面对不同类型的数据不兼容的问题。
namespace Seqlist
{
template <class T>//定义模板
class Seqlist
{
public:
Seqlist(size_t n = 10)//构造函数
:_a(new T[n])
, _size(0)
, capcity(n)
{}
~Seqlist()//析构函数
{
if (_a != NULL)
{
delete[] _a;
_capcity = 0;
_size = 0;
}
}
//...省略其它
private:
T* _a;//使用模板定义,可以兼容不同类型
size_t _size;
size_t capcity;
};
}