当前位置:网站首页>Function template_ Class template
Function template_ Class template
2022-06-25 07:40:00 【Who can keep company for a long time】
Why function templates
Project requirements : Implement multiple functions to return the maximum value of two numbers , Requirements can support char type 、int type 、double Type variable
// demo 15-2.c
#include <iostream>
using namespace std;
int Max(int a, int b)
{
return a>b ? a:b;
}
char Max(char a, char b)
{
return a>b ? a:b;
}
float Max(float a, float b)
{
return a>b ? a:b;
}
void main()
{
//char a = 'c';
int x = 1;
int y = 2;
cout<<"max(1, 2) = "<<Max(x, y)<<endl;
float a = 2.0;
float b = 3.0;
cout<<"max(2.0, 3.0) = "<<Max(a, b)<<endl;
system("pause");
return ;
}
actually , The above procedure , Just one “ function ” You can do it !
// demo 15-3.c
#include <iostream>
using namespace std;
/* int Max(int a, int b) { return a>b ? a:b; } char Max(char a, char b) { return a>b ? a:b; } float Max(float a, float b) { return a>b ? a:b; } */
//template Keyword telling C++ compiler I'm going to start generic programming , Please don't make mistakes at will
//T - Parameterized data type
template <typename T>
T Max(T a, T b){
return a>b ? a:b;
}
/* If T Use int Type invocation , It is equivalent to calling the following function int Max(int a, int b) { return a>b ? a:b; } */
void main()
{
//char a = 'c';
int x = 1;
int y = 2;
cout<<"max(1, 2) = "<<Max(x, y)<<endl; // Realize the automatic derivation of parameter types
cout<<"max(1, 2) = "<<Max<int>(x,y)<<endl;// Display type call
float a = 2.0;
float b = 3.0;
cout<<"max(2.0, 3.0) = "<<Max(a, b)<<endl;
system("pause");
return ;
}
Function template syntax
The so-called function template , It's actually building a universal function , Its function type and parameter type are not specified specifically , Use a virtual type to represent . This general function is called function template . Any function with the same body can be replaced by this template , You don't have to define multiple functions , Just define once in the template . When a function is called, the system replaces the virtual type in the template according to the type of the argument , Thus, the functions of different functions are realized .
Function template definition form
It consists of three parts : Template description + Function definition + Function template call
template < Type formal parameter table >
type Function name ( Form parameter table )
{
// Statement sequence
}
Template description
template < Type formal parameter table >
The form of the type parameter :
typename T1 , typename T2 , …… , typename Tn
or class T1 , class T2 , …… , class Tn
( notes :typename and class The effect is exactly the same as )Function definition
type Function name ( Form parameter table )
{
}
Be careful : The generic parameter of the template description must appear once in the function definition
Generic type parameters can be used in the function parameter table , You can also use general type parametersFunction template call
max(a, b); // Explicit type call
max(a, b); // Automatic data type derivation
4. template function
Function templates and function overloading
5. Function templates and function overloading
// demo 15-4.c
#include <iostream>
using namespace std;
template <typename T>
void Swap(T &a, T &b){
T t;
t = a;
a = b;
b = t;
cout<<"Swap The template function is called "<<endl;
}
/* void Swap(char &a, int &b){ int t; t = a; a = b; b = t; cout<<"Swap Ordinary functions are called "<<endl; } */
void main(void){
char cNum = 'c';
int iNum = 65;
// Case one , Template function and ordinary function coexist , The parameter type matches the ordinary overloaded function better
// Call ordinary functions
//Swap(cNum, iNum);
// The second case There is no ordinary function , Function templates can implicitly convert data types ?
// Conclusion : No implicit data type conversion is provided , Must be a strict match
//Swap(cNum, iNum);
system("pause");
return ;
}
The difference between function template and ordinary function :
Both are allowed to coexist
Function templates don't allow automatic type conversion
Ordinary functions can perform automatic type conversion
// demo 15-5.c
#include <iostream>
using namespace std;
// The first edition
int Max(int a, int b)
{
cout<<" call int Max(int a, int b)"<<endl;
return a>b ? a:b;
}
template<typename T>
T Max(T a, T b)
{
cout<<" call T Max(T a, T b)"<<endl;
return a>b ? a:b;
}
template <typename T>
T Max(T a, T b, T c){
cout<<" call T Max(T a, T b, T c)"<<endl;
return Max(Max(a, b), c);
}
// The second edition
int Max1(int a, int b)
{
cout<<" call int Max(int a, int b)"<<endl;
return a>b ? a:b;
}
template<typename T1, typename T2>
T1 Max1(T1 a, T2 b)
{
cout<<" call T Max1(T1 a, T2 b)"<<endl;
return a>b ? a:b;
}
void main(void){
int a = 1;
int b = 2;
// When both the function template and the normal function match the call , Choose the normal function first
//cout<<"Max(a, b)"<<Max(a, b)<<endl;
// If you explicitly use function templates , Then use <> Type list
//Max<>(a, b);
char c = 'a';
// If the function template will produce a better match , Using function templates
//Max1(c, a);
//Max(1.0, 2.0);
Max(3.0, 4.0, 5.0);
system("pause");
return ;
}
Function templates and ordinary functions together , Call rules :
1 Function templates can be overloaded like ordinary functions
2 C++ The compiler gives priority to ordinary functions
3 If the function template can produce a better match , Then select the template
4 You can restrict the compiler to match only through templates through the syntax of an empty template argument list
5. The compiler does not treat function templates as being able to handle any type of function
6. The compiler generates different functions from function templates through specific types
Use of class templates
1. Why class templates are needed
The definition and use of class templates and function templates are similar , Sometimes , There are two or more classes , Its function is the same , It's just that the data types are different , We can declare a class template through the following statement :
2. The class template is used to parameterize the type of data required by the class
3. Class templates are particularly important in supporting multiple data structures , The representation and algorithm of these data structures are not affected by the type of elements contained
Class template definition
Class template consists of template description and class description
Template description is the same as function template , as follows :
template < Type formal parameter table >
Class declaration
for example :
template
class ClassName
{
//ClassName Member function of
private :
Type DataMember;
}
A single class template uses
// demo 15-8.c
#include <iostream>
using namespace std;
template <typename T>
class A
{
public:
// The argument list of the function uses the virtual type
A(T t=0)
{
this->t = t;
}
// The return value of the member function uses the virtual type
T &getT()
{
return t;
}
private:
// Member variables use virtual types
T t;
};
void printA(A<int> &a){
cout<<a.getT()<<endl;
}
int main(void){
//1. Template classes define class objects , The specified type must be displayed
//2. If the template uses a constructor , Follow the calling rules of the constructor of the previous class
A<int> a(666);
cout<<a.getT()<<endl;
// Template class as function parameter
printA(a);
system("pause");
return 0;
}
Inherited class templates use
// demo 15-9.c
#include <iostream>
using namespace std;
// The combination of parent-child classes and template classes in inheritance
//1. Parent class general class , Subclasses are template classes , It is similar to the playing method of ordinary inheritance
//2. Subclasses are general classes , The parent class is the template class , When inheriting, the type parameter of the parent class must be instantiated in the subclass
//3. When both parent and child classes are template classes , The virtual type of the subclass can be passed to the parent class
/*class B { public: B(int b) { this->b = b; } private: int b; }; */
template <typename T>
class A
{
public:
// The argument list of the function uses the virtual type
A(T t)
{
this->t = t;
}
// The return value of the member function uses the virtual type
T &getT()
{
return t;
}
private:
// Member variables use virtual types
T t;
};
template <typename Tb>
class B: public A<int>
{
public:
B(Tb b):A<Tb>(b)
{
this->b = b;
}
private:
Tb b;
};
void printA(A<int> &a){
cout<<a.getT()<<endl;
}
int main(void){
//1. Template classes define class objects , The specified type must be displayed
//2. If the template uses a constructor , Follow the calling rules of the constructor of the previous class
A<int> a(666);
cout<<a.getT()<<endl;
B<int> b(888);
cout<<"b(888): "<<b.getT()<<endl;
// Template class as function parameter
printA(a);
system("pause");
return 0;
}
Conclusion : When subclasses inherit from template classes , You need to let the compiler know What is the data type of the parent class
1. Parent class general class , Subclasses are template classes , It is similar to the playing method of ordinary inheritance
2. Subclasses are general classes , The parent class is the template class , When inheriting, the type parameter of the parent class must be instantiated in the subclass
3. When both parent and child classes are template classes , The virtual type of the subclass can be passed to the parent class
4. All class template functions are written outside the class , In a cpp in
// demo 15-9.c
#include <iostream>
using namespace std;
template <typename T>
class A
{
public:
A(T t=0);
T &getT();
A operator +(const A &other);
void print();
private:
T t;
};
/* class A { public: A(int t=0); int &getT(); A operator +(const A &other); void print(); private: int t; }; */
template <typename T>
A<T>::A(T t)
{
this->t = t;
}
template <typename T>
T &A<T>::getT()
{
return t;
}
template <typename T>
A<T> A<T>::operator+(const A<T> &other){
A<T> tmp; // The inner type of a class can be declared or not
tmp.t =this->t + other.t;
return tmp;
}
template <typename T>
void A<T>::print(){
cout<<this->t<<endl;
}
int main(void){
A<int> a(666), b(888);
//cout<<a.getT()<<endl;
A<int> tmp = a + b;
tmp.print();
system("pause");
return 0;
}
summary :
In the same cpp Put the member function of the template class outside the class in the file , The following points need to be noted
1. Declare before function template < Type formal parameter table >
2. The class restricted field before the member function of the class must be accompanied by a virtual parameter list
3. When the returned variable is the object of the template class, you must bring the virtual parameter list
4. When the object of template class appears in the parameter of member function, the virtual parameter list must be brought
5. There is no restriction inside the member function
// demo.h
#pragma once
template <typename T>
class A
{
public:
A(T t=0);
T &getT();
A operator +(const A &other);
void print();
private:
T t;
};
// demo 15-10.c
#include "demo.h"
#include <iostream>
using namespace std;
template <typename T>
A<T>::A(T t)
{
this->t = t;
}
template <typename T>
T &A<T>::getT()
{
return t;
}
template <typename T>
A<T> A<T>::operator+(const A<T> &other){
A<T> tmp; // The inner type of a class can be declared or not
tmp.t =this->t + other.t;
return tmp;
}
template <typename T>
void A<T>::print(){
cout<<this->t<<endl;
}
int main(void){
A<int> a(666), b(888);
//cout<<a.getT()<<endl;
A<int> tmp = a + b;
tmp.print();
system("pause");
return 0;
}
Be careful : When the class template is declared (.h file ) And the implementation (.cpp or .hpp file ) Complete separation , Because of the special implementation of the class template , We should use... When using class templates #include contain Implementation part .cpp or .hpp file .
A special case Friend function
// demo 15-11.c
#include <iostream>
using namespace std;
template <typename T>
class A
{
public:
A(T t=0);
// Declare a friend function , To achieve two A Class object to add
template <typename T>
friend A<T> addA(const A<T> &a, const A<T> &b);
T &getT();
A operator +(const A &other);
void print();
private:
T t;
};
template <typename T>
A<T>::A(T t)
{
this->t = t;
}
template <typename T>
T &A<T>::getT()
{
return t;
}
template <typename T>
A<T> A<T>::operator+(const A<T> &other){
A tmp; // The inner type of a class can be declared or not
tmp.t =this->t + other.t;
return tmp;
}
template <typename T>
void A<T>::print(){
cout<<this->t<<endl;
}
//A Friend function of class , Is its good friend
template <typename T>
A<T> addA(const A<T> &a, const A<T> &b){
A<T> tmp;
cout<<"call addA()..."<<endl;
tmp.t = a.t + b.t;
return tmp;
}
int main(void){
A<int> a(666), b(888);
//cout<<a.getT()<<endl;
A<int> tmp = a + b;
A<int> tmp1 = addA<int>(a, b);
tmp.print();
tmp1.print();
system("pause");
return 0;
}
Conclusion :
(1) Declare friend functions inside the class , It must be written in the form
template
friend A addA (A &a, A &b);
(2) Friend function implementation Must be written as
template
A add(A &a, A &b)
{
//…
}
(3) Friend function call Must be written as
A c4 = addA(c1, c2);
Template classes and static members
// demo 15-12.c
#include <iostream>
using namespace std;
template <typename T>
class A
{
public:
A(T t=0);
T &getT();
A operator +(const A &other);
void print();
public:
static int count;
private:
T t;
};
template <typename T> int A<T>::count = 666;
template <typename T>
A<T>::A(T t)
{
this->t = t;
}
template <typename T>
T &A<T>::getT()
{
return t;
}
template <typename T>
A<T> A<T>::operator+(const A<T> &other){
A tmp; // The inner type of a class can be declared or not
tmp.t =this->t + other.t;
return tmp;
}
template <typename T>
void A<T>::print(){
cout<<this->t<<endl;
}
/* // When our virtual type T By int After instantiation , The template classes are as follows : class A { public: A(int t=0); int &getT(); A operator +(const A &other); void print(); public: static int count; private: int t; }; int A::count = 666; A::A(int t) { this->t = t; } int &A::getT() { return t; } A A::operator+(const A &other){ A tmp; // The inner type of a class can be declared or not tmp.t =this->t + other.t; return tmp; } void A::print(){ cout<<this->t<<endl; } */
/* // When our virtual type T By float After instantiation , The template classes are as follows : class A { public: A(float t=0); float &getT(); A operator +(const A &other); void print(); public: static int count; private: float t; }; int A::count = 666; A::A(float t) { this->t = t; } float &A::getT() { return t; } A A::operator+(const A &other){ A tmp; // The inner type of a class can be declared or not tmp.t =this->t + other.t; return tmp; } void A::print(){ cout<<this->t<<endl; } */
int main(void){
A<int> a(666), b(888);
A<int> tmp = a + b;
//A a(666), b(888);
//A tmp = a + b;
A<float> c(777), d(999);
a.count = 888;
cout<<"b.count:"<<b.count<<endl;
cout<<"c.count:"<<c.count<<endl;
cout<<"d.count:"<<d.count<<endl;
c.count = 1000;
cout<<" After modification , d.count:"<<d.count<<endl;
//tmp.print();
system("pause");
return 0;
}
summary :
1. Each template class instantiated from a class template has its own class template data member , All the objects of this template class share one static Data member
2. And non template classes static Data members are the same , Template class static Data members should also be defined and initialized in the scope of the file
3.static Data members can also use virtual type parameters T
Class template Usage Summary
Sum up the above introduction , You can declare and use class templates like this :
- First write an actual class .
- Name the type to be changed in this class ( Such as int To change to float or char) Use a virtual type name you specify ( In the example above T).
- Add a line before the class declaration , The format is :
template <typename Virtual type parameters >
Such as :
template
class A
{…}; // The class body - When you define an object with a class template, use the following form :
Class template name < Actual type name > Object name ;
or Class template name < Actual type name > Object name ( Argument table column );
Such as :
A cmp;
A cmp(3,7); - If you define member functions outside the class template , It should be written as a class template :
template <typename Virtual type parameters >
Function type Class template name < Virtual type parameters >:: Member function name ( Function parameter list column ) {…}
Some additions to class templates : - The type parameters of a class template can have one or more , Each type must be preceded by typename or class, Such as :
template <typename T1,typename T2>
class someclass
{…};
When defining the object, substitute the actual type name , Such as :
someclass<int, char> object; - Just like using classes , When using a class template, pay attention to its scope , Only use it to define objects within its valid scope .
- Template classes can also support inheritance , There is a hierarchical relationship , A class template can be used as a base class , Derived template class .
Class template practice
1) Please design an array template class ( Vector ), Finish right int、char、float、double And any custom class and other type elements .
demand
a. Implement constructors
b. Implement the copy constructor
c. Realization cout << operation
d. Implement subscript accessors [] Overload operation of
e. Realization = The number operator overloads
// demo 15-13 Vector.h
#include <iostream>
using namespace std;
template <typename T>
class Vector
{
//Vector<int> a(10); cout<<a;
friend ostream &operator<< <T> (ostream &out, const Vector &object);
public:
Vector(int size = 128); // Constructors
Vector(const Vector &object); // copy constructor
//Vector<int> a(10); a
//operator<<()
int getLength();// Get the number of elements stored internally
//Vector<int> a1, a2; a1[0]
T& operator[](int index);
// Realization = operators overloading
//a1 = a2 = a3;
Vector &operator=(const Vector &object);
~Vector(); // Destructor
private:
T *m_base;
int m_len;
};
// demo 15-13 Vector.cpp
#include <iostream>
using namespace std;
#include "Vector.h"
//cout<<a<<b<<c;
template<typename T>
ostream &operator<<(ostream &out, const Vector<T> &object){
for(int i=0; i<object.m_len; i++){
out << object.m_base[i] << " ";//Student a("18"," Li Xiaohua "); cout<< a<<endl;
}
out<<endl;
return out;
}
template <typename T>
Vector<T>::Vector(int size){
// Constructors
if(size > 0){
m_len = size;
m_base = new T[m_len];
}
}
template <typename T>
Vector<T>::Vector(const Vector<T> &object){
// copy constructor
// Allocate space according to the number of object elements passed in
m_len = object.m_len;
m_base = new T[m_len];
// Copy of data
for(int i=0; i<m_len; i++){
m_base[i] = object.m_base[i];
}
}
template <typename T>
int Vector<T>::getLength(){
return m_len;
}
//Vector<int> a1, a2; a1[0]
template <typename T>
T& Vector<T>::operator[](int index){
return m_base[index];// return *(m_base+index);
}
// Realization = operators overloading
//a1 = a2 = a3;
template <typename T>
Vector<T> &Vector<T>::operator=(const Vector<T> &object){
if(m_base != NULL){
delete[] m_base;
m_base = NULL;
m_len = 0;
}
// Allocate space according to the number of object elements passed in
m_len = object.m_len;
m_base = new T[m_len];
// Copy of data
for(int i=0; i<m_len; i++){
m_base[i] = object.m_base[i];
}
return *this; // a3 = a2 = a1;
}
template <typename T>
Vector<T>::~Vector(){
// Destructor
if(m_base != NULL){
delete[] m_base;
m_base = NULL;
m_len = 0;
}
}
// demo 15-13 13_ Class template practice .cpp
#include <iostream>
using namespace std;
#include "Vector.cpp"
class Student{
friend ostream &operator<<(ostream &out, const Student &object);
public:
Student(){
age = 0;
name[0] = '\0';
}
Student(int _age, char *_name){
age = _age;
strcpy_s(name, 64, _name);
}
void print(){
cout<<name<<", "<<age<<endl;
}
~Student(){
}
private:
int age;
char name[64];
};
ostream &operator<<(ostream &out, const Student &object){
out<<"("<<object.name<<" , "<<object.age<<")";
return out;
}
int main(){
Student s1(18, " Li Xiaohua ");
Student s2(19, " Wang cannon ");
Vector<Student *> studentVector(2);
studentVector[0] = &s1;
studentVector[1] = &s2;
/*for(int i=0; i<studentVector.getLength(); i++){ studentVector[i].print(); }*/
cout<<studentVector<<endl;
system("pause");
//ostream cout;
Vector<int> myVector(10);
//int a[10]; len: sizeof(a)/sizeof(a[0])
for(int i=0; i<myVector.getLength(); i++){
myVector[i] = i;
}
cout<<myVector<<endl;
system("pause");
for(int i=0; i<myVector.getLength(); i++){
cout<<myVector[i]<<endl;
}
// Test the copy constructor
Vector<int> myIntVector1(myVector);
cout<<"myIntVector1 The elements in are as follows :"<<endl;
for(int i=0; i<myIntVector1.getLength(); i++){
cout<<myIntVector1[i]<<endl;
}
cout<<"---end---"<<endl;
// Test assignment operator overloading
Vector<int> myIntVector2(1);
myIntVector2 = myIntVector1;
cout<<"myIntVector2 The elements in are as follows :"<<endl;
for(int i=0; i<myIntVector1.getLength(); i++){
cout<<myIntVector1[i]<<endl;
}
cout<<"---end---"<<endl;
Vector<float> myVector1(10);
//int a[10]; len: sizeof(a)/sizeof(a[0])
for(int i=0; i<myVector1.getLength(); i++){
myVector1[i] = i*0.1f;
}
for(int i=0; i<myVector1.getLength(); i++){
cout<<myVector1[i]<<endl;
}
system("pause");
return 0;
}
边栏推荐
- TEMPEST HDMI泄漏接收 2
- 鸿蒙页面菜单的选择
- 13 `bs_duixiang.tag标签`得到一个tag对象
- 【批处理DOS-CMD命令-汇总和小结】-cmd扩展命令、扩展功能(cmd /e:on、cmd /e:off)
- Without "rice", you can cook "rice". Strategy for retrieving missing ground points under airborne lidar forest using "point cloud intelligent mapping"
- Zhugeliang vs pangtong, taking distributed Paxos
- Why "New Year's Eve", the original memory burst!
- smartBugs安装小问题总结
- Hanxin's trick: consistent hashing
- Weimeisi new energy rushes to the scientific innovation board: the annual revenue is 1.7 billion, and the book value of accounts receivable is nearly 400million
猜你喜欢
VectorDraw Web Library 10.10
正版photoshop2022购买体验经历分享
13 `bs_duixiang.tag标签`得到一个tag对象
Explain distributed raft with dynamic diagram
LabVIEW generate application (exe) and installer
13 `bs_ duixiang. Tag tag ` get a tag object
JMeter introduction practice ----- use of global variables and local variables
Chuantu microelectronics 𞓜 subminiature package isolated half duplex 485 transceiver
Evolution of Alibaba e-commerce architecture
14 bs对象.节点名称.name attrs string 获取节点名称 属性 内容
随机推荐
【批处理DOS-CMD命令-汇总和小结】-cmd扩展命令、扩展功能(cmd /e:on、cmd /e:off)
【LeetCode】two num·两数之和
Genuine photoshop2022 purchase experience sharing
【批处理DOS-CMD命令-汇总和小结】-文件与目录操作命令(md、rd、xcopy、dir、cd、set、move、copy、del、type、sort)
What common APIs are involved in thread state changes
高考志愿填报,为啥专业最后考虑?
keepalived監控進程,自動重啟服務進程
Tupu software digital twin 3D wind farm, offshore wind power of smart wind power
鸿蒙页面菜单的选择
海思3559 sample解析:vio
Harmony food menu interface
【批处理DOS-CMD命令-汇总和小结】-添加注释命令(rem或::)
栅格地图(occupancy grid map)构建
Ns32f103c8t6 can perfectly replace stm32f103c8t6
The e-book "action guide for large organizations to further promote zero code application platform" was officially released!
【批處理DOS-CMD命令-匯總和小結】-外部命令-cmd下載命令、抓包命令(wget)
[batch dos-cmd command - summary and summary] - add comment command (REM or::)
Tuwei Digital Isolator and interface chip can perfectly replace imported brands Ti and ADI
Sichuan earth microelectronics ca-is1300 isolated operational amplifier for current detection is on the market
VectorDraw Web Library 10.10