【C/C++学院】(11)泛型编程/函数模板/类模板

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 main(){int a = 1, b = 2;swap(a, b);float a1 = 1, b1 = 2;swap(a1, b1);system("pause");} #include "iostream"using namespace std;//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");}2.函数模板加强#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");} 3. 函数模板遇上函数重载

函数模板可以像普通函数一样被重载

C++编译器优先考虑普通函数

如果函数模板可以产生一个更好的匹配,那么选择模板

可以通过空模板实参列表的语法限定编译器只通过模板匹配

/*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;}4.函数模板本质探究:

编译器并不是把函数模板处理成能够处理任意类型的函数

编译器从函数模板通过具体类型产生不同的函数

编译器会对函数模板进行两次编译

在声明的地方对模板代码本身进行编译

在调用的地方对参数替换后的代码进行编译

#include "cstdlib"using namespace std;/*函数模板的深入理― 编译器并不是把函数模板处理成能够处理任意类型的函数― 编译器从函数模板通过具体类型产生不同的函数― 编译器会对函数模板进行两次编译―在声明的地方对模板代码本身进行编译―在调用的地方对参数替换后的代码进行编译*///template告诉编译器,这里开始进行泛型编程//typename告诉编译器,类型名称为T 编译器你看到类型T 不要乱报错。。。。//T为类型,类型参数化而已template<typename T>void swap2(T &a, T &b){T t = a;a = b;b = t;}int main(){int x = 1;int y = 2;//泛型编程的调用方式分为两种//自动类型 推导调用swap2<int>(x, y);//printf("\n%d, %d", x, y);float x1 = 1.0;float y1 = 2.0;//具体类 显示调用swap2<float>(x1, y1);//printf("\n%f, %f", x1, y1);cout << "hello…." << endl;system("pause");return 0;}

g++ -S 1.cpp 生成了1.s

分析1.s

.file "1.cpp".lcomm __ZStL8__ioinit, 1, 1.def ___main;.scl 2;.type 32;.endef.section.rdata, "dr"LC2:.ascii "hello….\0"LC3 :.ascii "pause\0".text.globl _main.def _main;.scl 2;.type 32;.endef_main :pushl %ebpmovl %esp, %ebpandl $ – 16, %espsubl $32, %espcall ___mainmovl $1, 28(%esp)movl $2, 24(%esp)leal 24(%esp), %eaxmovl %eax, 4(%esp)leal 28(%esp), %eaxmovl %eax, (%esp)call __Z5swap2IiEvRT_S1_ //24-49movl $0x3f800000, %eaxmovl %eax, 20(%esp)movl $0x40000000, %eaxmovl %eax, 16(%esp)leal 16(%esp), %eaxmovl %eax, 4(%esp)leal 20(%esp), %eaxmovl %eax, (%esp)call __Z5swap2IfEvRT_S1_ //33-69movl $LC2, 4(%esp)movl $__ZSt4cout, (%esp)call __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKcmovl $__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)movl %eax, (%esp)call __ZNSolsEPFRSoS_Emovl $LC3, (%esp)call _systemmovl $0, %eaxleaveret.section.text$_Z5swap2IiEvRT_S1_, "x".linkonce discard.globl __Z5swap2IiEvRT_S1_.def __Z5swap2IiEvRT_S1_;.scl 2;.type 32;.endef__Z5swap2IiEvRT_S1_ :pushl %ebpmovl %esp, %ebpsubl $16, %espmovl 8(%ebp), %eaxmovl(%eax), %eaxmovl %eax, -4(%ebp)movl 12(%ebp), %eaxmovl(%eax), %edxmovl 8(%ebp), %eaxmovl %edx, (%eax)movl 12(%ebp), %eaxmovl – 4(%ebp), %edxmovl %edx, (%eax)leaveret.section.text$_Z5swap2IfEvRT_S1_, "x".linkonce discard.globl __Z5swap2IfEvRT_S1_.def __Z5swap2IfEvRT_S1_;.scl 2;.type 32;.endef__Z5swap2IfEvRT_S1_ :pushl %ebpmovl %esp, %ebpsubl $16, %espmovl 8(%ebp), %eaxmovl(%eax), %eaxmovl %eax, -4(%ebp)movl 12(%ebp), %eaxmovl(%eax), %edxmovl 8(%ebp), %eaxmovl %edx, (%eax)movl 12(%ebp), %eaxmovl – 4(%ebp), %edxmovl %edx, (%eax)leaveret.text.def ___tcf_0;.scl 3;.type 32;.endef___tcf_0 :pushl %ebpmovl %esp, %ebpsubl $24, %espmovl $__ZStL8__ioinit, (%esp)call __ZNSt8ios_base4InitD1Evleaveret.def __Z41__static_initialization_and_destruction_0ii;.scl 3;.type 32;.endef__Z41__static_initialization_and_destruction_0ii :pushl %ebpmovl %esp, %ebpsubl $24, %espcmpl $1, 8(%ebp)jne L5cmpl $65535, 12(%ebp)jne L5movl $__ZStL8__ioinit, (%esp)call __ZNSt8ios_base4InitC1Evmovl $___tcf_0, (%esp)call _atexitL5 :leaveret.def __GLOBAL__sub_I_main;.scl 3;.type 32;.endef__GLOBAL__sub_I_main :pushl %ebpmovl %esp, %ebpsubl $24, %espmovl $65535, 4(%esp)movl $1, (%esp)call __Z41__static_initialization_and_destruction_0iileaveret.section.ctors, "w".align 4.long __GLOBAL__sub_I_main.def __ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_;.scl 2;.type 32;.endef.def __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc;.scl 2;.type 32;.endef.def __ZNSolsEPFRSoS_E;.scl 2;.type 32;.endef.def _system;.scl 2;.type 32;.endef.def __ZNSt8ios_base4InitD1Ev;.scl 2;.type 32;.endef.def __ZNSt8ios_base4InitC1Ev;.scl 2;.type 32;.endef.def _atexit;.scl 2;.type 32;.endef 5.类模板基础#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");}6.类模板遇上友元函数#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 main(){Complex<int>c1(1, 2);Complex<int>c2(3, 4);Complex<int>c3 = c1 + c2;c3.print();system("pause");}7.类模板遇上static#include "iostream"using namespace std;const double pi = 3.14159;template<typename T>class Circle{T radius;static int total;//类模板的静态数据成员public:Circle(T r = 0) { radius = r; total++; }void Set_Radius(T r) { radius = r; }double Get_Radius() { return radius; }double Get_Girth(){ return 2 * pi * radius; }double Get_Area(){ return pi * radius * radius; }static int ShowTotal();//类模板的静态成员函数};template<typename T>int Circle<T>::total = 0;template<typename T>int Circle<T>::ShowTotal(){return total;}void main(){Circle<int> A, B;//建立了2个对象A.Set_Radius(16);cout << "A.Radius = " << A.Get_Radius() << endl;cout << "A.Girth = " << A.Get_Girth() << endl;cout << "A.Area = " << A.Get_Area() << endl;B.Set_Radius(105);cout << "B.radius = " << B.Get_Radius() << endl;cout << "B.Girth=" << B.Get_Girth() << endl;cout << "B.Area = " << B.Get_Area() << endl;cout << "Total1=" << Circle<int>::ShowTotal() << endl;//显示建立的对象数cout << endl;Circle<double> X(6.23), Y(10.5), Z(25.6);//建立了3个对象cout << "X.Radius = " << X.Get_Radius() << endl;cout << "X.Girth = " << X.Get_Girth() << endl;cout << "X.Area = " << X.Get_Area() << endl;cout << "Y.radius = " << Y.Get_Radius() << endl;cout << "Y.Girth=" << Y.Get_Girth() << endl;cout << "Y.Area = " << Y.Get_Area() << endl;cout << "Z.Girth=" << Z.Get_Girth() << endl;cout << "Z.Area = " << Z.Get_Area() << endl;cout << "Total2=" << Circle<double>::ShowTotal() << endl;//显示建立的对象数system("pause");}

却只能这样。只有对爱的人,我们才会斤斤计较,锱铢必较。

【C/C++学院】(11)泛型编程/函数模板/类模板

相关文章:

你感兴趣的文章:

标签云: