当前位置:网站首页>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;
}
边栏推荐
- MySQL facet 01
- Why "New Year's Eve", the original memory burst!
- 高数基础_函数的奇偶性
- Sichuan Tuwei ca-if1051 can transceiver has passed aec-q100 grade 1 certification
- lebel只想前面有星号,但是不想校验
- Estimation of dense forest volume based on LIDAR point cloud with few ground points
- 【批处理DOS-CMD命令-汇总和小结】-外部命令-cmd下载命令、抓包命令(wget)
- Large funds support ecological construction, and Plato farm builds a real meta universe with Dao as its governance
- 点云智绘在智慧工地中的应用
- 14 BS object Node name Name attrs string get node name attribute content
猜你喜欢

VectorDraw Developer Framework 10.10

Chuantu microelectronics breaks through the high-end isolator analog chip market with ca-is3062w

为什么要“除夕”,原来是内存爆了!

smartBugs安装小问题总结

Application scheme | application of Sichuan earth microelectronics ca-is398x in PLC field

Authentique Photoshop 2022 expérience d'achat partage

栅格地图(occupancy grid map)构建

Advanced mathematics foundation_ Parity of functions

Full range of isolator chips with integrated isolated power supply

【pytest】修改allure报告中的logo及参数化
随机推荐
VectorDraw Developer Framework 10.10
数据可视化没有重点怎么办?
CPDA | how to start the growth path of data analysts?
Authentique Photoshop 2022 expérience d'achat partage
Construction of occupancy grid map
[batch dos-cmd command - summary and summary] - external command -cmd download command and packet capture command (WGet)
14 BS object Node name Name attrs string get node name attribute content
稳压二极管的原理,它有什么作用?
Orcad Schematic常用功能
【批处理DOS-CMD命令-汇总和小结】-CMD窗口的设置与操作命令(cd、title、mode、color、pause、chcp、exit)
基于地面点稀少的LiDAR点云的茂密森林蓄积量估算
Without "rice", you can cook "rice". Strategy for retrieving missing ground points under airborne lidar forest using "point cloud intelligent mapping"
【批处理DOS-CMD命令-汇总和小结】-应用程序启动和调用、服务和进程操作命令(start、call、)
Keepalived monitors the process and automatically restarts the service process
为什么要“除夕”,原来是内存爆了!
LeetCode 每日一题——515. 在每个树行中找最大值
Unity3D邪门实现之GUI下拉菜单Dropdown设计无重复项
lebel只想前面有星号,但是不想校验
Harmony美食菜单界面
点云智绘在智慧工地中的应用