泛型编程,摸板函数模板类

C++泛型编程实战
本文介绍了C++中的泛型编程基础知识,包括泛型函数和泛型类的定义与使用,探讨了泛型编程与函数重载之间的交互,并展示了如何利用泛型实现排序算法等实用功能。

1、泛型编程基础

泛型函数

#include "iostream"
using namespace std;

void  swap(int &a, int &b)
{
	int c ;
	c = a;
	a = b;
	b = c;
}

void  swap(float &a, float &b)
{
	float c ;
	c = a;
	a = b;
	b = c;
}
void main11()
{
	int a = 1, b = 2;
	swap(a, b);
	float a1 = 1, b1 = 2;
	swap(a1, b1);
	system("pause");
}


//template关键字告诉c++编译器,现在开始泛型编程
//typename 告诉c++编译器,T为类型(T为类型,可以参数化,int float),你不要乱报错
//类型参数化。。。。。。。
template<typename T>
void swap2(T &a, T &b)
{
	T c;
	c = a;
	a = b;
	b = c;
}

void  main()
{
	//泛型编程的调用方式有两种
	//自动类型推导
	int x =1, y =2;
	swap2(x, y);
	printf("x:%d y:%d \n", x, y);

	float x1= 1.0, y1 = 2.0;

	//具体类型调用
	swap2<float>(x1, y1);
	printf("x1:%f y1:%f \n", x1, y1);
	system("pause");
}
泛型类

#include <iostream>
using namespace std;

//定义一个类模板

template<typename T>
class AA
{
public:
	AA(T a)
	{
		this->a = a;
	}
	void setA(T a)
	{
		this->a = a;
	}
	T getA()
	{
		return this->a
	}
protected:
private:
	T a;
};

class BB : public AA<int>
{
public:
	//BB(int a, int b) : AA(a) 
	BB(int a, int b) : AA<int>(a) 
	{
		this->b = b;
	}

private:
	int b;
};

void main()
{
	//要把类模板具体成类型后,才能定义变量
	AA<int> a(10);

	BB b1(1, 2);
	system("pause");
}


2、当泛型遇到重载

/*
	1 函数模板可以像普通函数一样被重载
	2 C++编译器优先考虑普通函数
	3 如果函数模板可以产生一个更好的匹配,那么选择模板
	4 可以通过空模板实参列表的语法限定编译器只通过模板匹配
*/

/*
函数模板不允许自动类型转化
普通函数能够进行自动类型转换
*/

#include <iostream>
using namespace std;


int Max(int a, int b)
{
	cout<<"int Max(int a, int b)"<<endl;
	return a > b ? a : b;
}

template<typename T>
T Max(T a, T b)
{
	cout<<"T Max(T a, T b)"<<endl;
	return a > b ? a : b;
}

template<typename T>
T Max(T a, T b, T c)
{
	cout<<"T Max(T a, T b, T c)"<<endl;
	return Max(Max(a, b), c);
}


void main()
{
	int a = 1;
	int b = 2;

	cout<<Max(a, b)<<endl;   // 调用重载函数
	cout<<Max<>(a, b)<<endl; // 这时候会强制调用泛型函数

	cout<<Max(3.0, 4.0)<<endl;

	cout<<Max(5.0, 6.0, 7.0)<<endl;

	cout<<Max('a', 100)<<endl;
	system("pause");
	return ;
}

3、函数模板加强,排序模板

#include "iostream"
using namespace std;

template<typename T>
void sortArray(T *a, int num)
{
	int i =0, j = 0;
	T tmp;

	for (i=0; i<num; i++)
	{
		for (j=i; j<num; j++)
		{
			if (a[i] < a[j])
			{
				tmp = a[i];
				a[i] = a[j];
				a[j] = tmp;
			}
		}
	}
}

template<class T>
void printfArray(T *a, int num)
{
	cout<<endl;
	for (int i=0; i<num; i++)
	{
		cout<<a[i]<<" ";
	}
}
void main()
{
	int a[10] = {1, 3, 4, 5,2, 3,44, 6,3};
	int num = sizeof(a)/sizeof(*a);
	sortArray<int>(a, num);
	printfArray<int>(a, num);

	char buf[] = "163addeadfdsafdsaf";
	int len = strlen(buf);

	sortArray<char>(buf, len);
	printfArray<char>(buf, len);



	system("pause");
}

4、模板实现本质是编译器会在编译的时候扫面模板函数记录下来,在用的时候会自动生成一个函数重载,其实和我们自己写函数重载时一样的,只不过是编译器为我们做了,可以看编译后的汇编源码,会发现没添加新的类型时候都会生成一个对应的重载函数

5、当友元函数碰上模板类的时候,如果将声明和实现分开写的情况下回出现编译不过,处理方法是声明和实现写到一起声明诚内联函数。没有别的处理办法

#include <iostream>
using namespace std;

template<class T>
class Complex
{ 
public:
	Complex( T r =0, T i =0 );
	Complex(T a) { Real = a ;  Image = 0 ; } 
	 void print() const;
	 friend Complex<T>operator+(Complex<T>&c1,Complex<T>&c2)
	{
		T r = c1.Real + c2.Real ;     T i = c1.Image+c2.Image ;
		return Complex<T>( r, i ) ;
	}
	//friend Complex operator- ( const Complex<T> & c1, const Complex<T> & c2 );
	//friend Complex operator- ( const Complex<T> & c );
private:  
	T  Real, Image ;
};

template<class T>
Complex<T>::Complex( T r, T i )
{ 
	Real = r ;  Image = i ; 
}

/*
"class Complex<int> __cdecl operator+(class Complex<int> &,class Complex<int> &)" (??H@YA?AV?$Complex@H@@AAV0@0@Z),该符号在函数 _main 中被引用
	1>E:\01-work\09-就业班0415\day16\泛型编程\Debug\泛型编程.exe : fatal error LNK1120: 1 个无法解析的外部命令
	========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
	*/


// template<class T> 
// Complex<T>operator+(Complex<T>&c1,Complex<T>&c2)
// { 
// 	T r = c1.Real + c2.Real ;     T i = c1.Image+c2.Image ;
// 	return Complex<T>( r, i ) ;
// }

template<typename T> 
void Complex<T>::print()const
{ 
	cout << '(' << Real << " , " << Image << ')' << endl; 
}


void main61()
{
	Complex<int>c1(1, 2);
	Complex<int>c2(3, 4);

	Complex<int>c3 = c1 + c2;
	c3.print();

	system("pause");
}
6、当摸板类函数遇上static会为实际使用的每一种类添加一个静态成员



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值