zl程序教程

您现在的位置是:首页 >  后端

当前栏目

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

C++模板编程泛型 函数 11 学院
2023-09-14 08:57:16 时间
//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 i++)

 for (j = i; j 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 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");


函数模板遇上函数重载

函数模板可以像普通函数一样被重载  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.函数模板本质探究:

编译器并不是把函数模板处理成能够处理任意类型的函数 编译器从函数模板通过具体类型产生不同的函数
― 编译器并不是把函数模板处理成能够处理任意类型的函数 ― 编译器从函数模板通过具体类型产生不同的函数 ― 编译器会对函数模板进行两次编译 ―在声明的地方对模板代码本身进行编译 ―在调用的地方对参数替换后的代码进行编译 //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

call __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc movl $__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp) movl %eax, (%esp) call __ZNSolsEPFRSoS_E movl $LC3, (%esp) call _system movl $0, %eax leave .section.text$_Z5swap2IiEvRT_S1_, "x" .linkonce discard .globl __Z5swap2IiEvRT_S1_ .def __Z5swap2IiEvRT_S1_;.scl 2;.type 32;.endef __Z5swap2IiEvRT_S1_ : pushl %ebp movl %esp, %ebp subl $16, %esp movl 8(%ebp), %eax movl(%eax), %eax movl %eax, -4(%ebp) movl 12(%ebp), %eax movl(%eax), %edx movl 8(%ebp), %eax movl %edx, (%eax) movl 12(%ebp), %eax movl - 4(%ebp), %edx movl %edx, (%eax) leave .section.text$_Z5swap2IfEvRT_S1_, "x" .linkonce discard .globl __Z5swap2IfEvRT_S1_ .def __Z5swap2IfEvRT_S1_;.scl 2;.type 32;.endef __Z5swap2IfEvRT_S1_ : pushl %ebp movl %esp, %ebp subl $16, %esp movl 8(%ebp), %eax movl(%eax), %eax movl %eax, -4(%ebp) movl 12(%ebp), %eax movl(%eax), %edx movl 8(%ebp), %eax movl %edx, (%eax) movl 12(%ebp), %eax movl - 4(%ebp), %edx movl %edx, (%eax) leave .text .def ___tcf_0;.scl 3;.type 32;.endef ___tcf_0 : pushl %ebp movl %esp, %ebp subl $24, %esp movl $__ZStL8__ioinit, (%esp) call __ZNSt8ios_base4InitD1Ev leave .def __Z41__static_initialization_and_destruction_0ii;.scl 3;.type 32;.endef __Z41__static_initialization_and_destruction_0ii : pushl %ebp movl %esp, %ebp subl $24, %esp cmpl $1, 8(%ebp) jne L5 cmpl $65535, 12(%ebp) jne L5 movl $__ZStL8__ioinit, (%esp) call __ZNSt8ios_base4InitC1Ev movl $___tcf_0, (%esp) call _atexit leave .def __GLOBAL__sub_I_main;.scl 3;.type 32;.endef __GLOBAL__sub_I_main : pushl %ebp movl %esp, %ebp subl $24, %esp movl $65535, 4(%esp) movl $1, (%esp) call __Z41__static_initialization_and_destruction_0ii leave .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 个 ==========


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;
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++中的模板,为了能让大家更好地体会到用模板多是件美事!我们将会举例说明,大家可以试着把自己带入到文章中,跟着思路去阅读和思考,真的会很有意思!如果你对网络流行梗有了解,读起来将会更有意思!
【C++要笑着学】泛型编程 | 函数模板 | 函数模板实例化 | 类模板(一) 本章将正式开始介绍C++中的模板,为了能让大家更好地体会到用模板多是件美事!我们将会举例说明,大家可以试着把自己带入到文章中,跟着思路去阅读和思考,真的会很有意思!如果你对网络流行梗有了解,读起来将会更有意思!