1. Class template syntax
Class template function:
Create a general class. The member data types in the class can be represented by a virtual type without specific formulation.
Class template syntax:
template<typename T> class
Template - declare the creation of a template
typename - the symbol behind the surface is a data type, which can be replaced by class
T-A common data type whose name can be replaced, usually in uppercase letters
2. Difference between class template and function template
There are two differences between class templates and function templates:
- Class templates do not use automatic type derivation
- Class templates can have default parameters in the template parameter list
#include <string> //Class template template<class NameType, class AgeType = int> class Person { public: Person(NameType name, AgeType age) { this->mName = name; this->mAge = age; } void showPerson() { cout << "name: " << this->mName << " age: " << this->mAge << endl; } public: NameType mName; AgeType mAge; }; //1. Class templates do not use automatic type derivation void test01() { // Person p("Monkey King", 1000)// Automatic type derivation is not allowed when error class templates are used Person <string ,int>p("Sun WuKong", 1000); //The class template must be used in a way that displays the specified type p.showPerson(); } //2. Class templates can have default parameters in the template parameter list void test02() { Person <string> p("Zhu Bajie", 999); //The template parameter list in the class template can specify default parameters p.showPerson(); } int main() { test01(); test02(); system("pause"); return 0; }
Summary:
- Class templates can only be used to display the specified type
- The template parameter list in the class template can have default parameters
3. Creation time of member function in class template
The creation timing of member functions in class templates is different from that in ordinary classes:
- Member functions in ordinary classes can be created from the beginning
- Member functions in class templates are created only when called
Code example:
class Person1 { public: void showPerson1() { cout << "Person1 show" << endl; } }; class Person2 { public: void showPerson2() { cout << "Person2 show" << endl; } }; template<class T> class MyClass { public: T obj; //The member functions in the class template are not created at the beginning, but are generated when the template is called void fun1() { obj.showPerson1(); } void fun2() { obj.showPerson2(); } }; void test01() { MyClass<Person1> m; m.fun1(); //m.fun2();// There will be an error in compilation, which means that the function call will create the member function } int main() { test01(); system("pause"); return 0; }
Summary: the member functions in the class template are not created at the beginning, but only when called
4. Class template object as function parameter
Learning objectives:
- The object instantiated by the class template passes parameters to the function
There are three ways to transfer in:
- Specify the type passed in - displays the data type of the object directly
- Parameter templating - changes parameters in an object into templates for transfer
- Whole class templating - pass this object type templating
Code example:
#include <string> //Class template template<class NameType, class AgeType = int> class Person { public: Person(NameType name, AgeType age) { this->mName = name; this->mAge = age; } void showPerson() { cout << "name: " << this->mName << " age: " << this->mAge << endl; } public: NameType mName; AgeType mAge; }; //1. Specifies the type of incoming void printPerson1(Person<string, int> &p) { p.showPerson(); } void test01() { Person <string, int >p("Sun WuKong", 100); printPerson1(p); } //2. Parameter Templating template <class T1, class T2> void printPerson2(Person<T1, T2>&p) { p.showPerson(); cout << "T1 The type of is: " << typeid(T1).name() << endl; cout << "T2 The type of is: " << typeid(T2).name() << endl; } void test02() { Person <string, int >p("Zhu Bajie", 90); printPerson2(p); } //3. Entire class Templating template<class T> void printPerson3(T & p) { cout << "T The type of is: " << typeid(T).name() << endl; p.showPerson(); } void test03() { Person <string, int >p("Tang Monk", 30); printPerson3(p); } int main() { test01(); test02(); test03(); system("pause"); return 0; }
Summary:
- Objects created through class templates can pass parameters to functions in three ways
- The first one is widely used: specify the type of incoming
5. Class template and inheritance
When class templates encounter inheritance, you should pay attention to the following points:
- When the parent class inherited by the subclass is a class template, when declaring the subclass, specify the type of T in the parent class
- If not specified, the compiler cannot allocate memory to subclasses
- If you want to flexibly specify the type of T in the parent class, the child class also needs to be changed into a class template
Code example:
template<class T> class Base { T m; }; //class Son:public Base / / error. In c + + compilation, you need to allocate memory for subclasses. You must know the type of T in the parent class before you can inherit downward class Son :public Base<int> //You must specify a type { }; void test01() { Son c; } //The class template inherits the class template. You can use T2 to specify the T type in the parent class template<class T1, class T2> class Son2 :public Base<T2> { public: Son2() { cout << typeid(T1).name() << endl; cout << typeid(T2).name() << endl; } }; void test02() { Son2<int, char> child1; } int main() { test01(); test02(); system("pause"); return 0; }
Summary: if the parent class is a class template, the child class needs to specify the data type of T in the parent class
6. Out of class implementation of class template member function
Objective: be able to master the implementation of member functions outside the class in the class template
Code example:
#include <string> //Implementation outside class of member function in class template template<class T1, class T2> class Person { public: //Member function class declaration Person(T1 name, T2 age); void showPerson(); public: T1 m_Name; T2 m_Age; }; //Constructor out of class implementation template<class T1, class T2> Person<T1, T2>::Person(T1 name, T2 age) { this->m_Name = name; this->m_Age = age; } //Out of class implementation of member functions template<class T1, class T2> void Person<T1, T2>::showPerson() { cout << "full name: " << this->m_Name << " Age:" << this->m_Age << endl; } void test01() { Person<string, int> p("Tom", 20); p.showPerson(); } int main() { test01(); system("pause"); return 0; }
Summary: when the member function in the class template is implemented outside the class, the template parameter list needs to be added
7. Preparation of class template by document
Objectives:
- Master the problems and solutions arising from the preparation of class template member function sub files
Question: - The member function in the class template is created at the call stage, resulting in the link failure when writing the file
solve: - Solution 1: include directly cpp source file
- Solution 2: write the declaration and implementation to the same file and change the suffix to hpp, hpp is the name of the contract, not mandatory
Code example:
person.hpp
#pragma once #include <iostream> using namespace std; #include <string> template<class T1, class T2> class Person { public: Person(T1 name, T2 age); void showPerson(); public: T1 m_Name; T2 m_Age; }; //Constructor out of class implementation template<class T1, class T2> Person<T1, T2>::Person(T1 name, T2 age) { this->m_Name = name; this->m_Age = age; } //Out of class implementation of member functions template<class T1, class T2> void Person<T1, T2>::showPerson() { cout << "full name: " << this->m_Name << " Age:" << this->m_Age << endl; }
main.cpp
#include<iostream> using namespace std; //#include "person.h" #include "person.cpp" / / solution 1: include the cpp source file //Solution 2: write the declaration and implementation together, and change the file suffix to hpp #include "person.hpp" void test01() { Person<string, int> p("Tom", 10); p.showPerson(); } int main() { test01(); system("pause"); return 0; }
Summary: the second solution is to write the class template member functions together and change the suffix to hpp
8. Class templates and friends
Objectives:
- Master the in class and out of class implementation of class template and friend function
Global function class implementation - just declare friends directly in the class
Out of class implementation of global functions - you need to let the compiler know the existence of global functions in advance
Code example:
#include <string> //2. The global function is implemented outside the friend class - first make the function template declaration. The function template definition is made below, and the friend is made template<class T1, class T2> class Person; //If a function template is declared, you can write the implementation to the back. Otherwise, you need to write the implementation to the front of the class for the compiler to see in advance //template<class T1, class T2> void printPerson2(Person<T1, T2> & p); template<class T1, class T2> void printPerson2(Person<T1, T2> & p) { cout << "Out of class implementation ---- full name: " << p.m_Name << " Age:" << p.m_Age << endl; } template<class T1, class T2> class Person { //1. Global functions are implemented within friend classes friend void printPerson(Person<T1, T2> & p) { cout << "full name: " << p.m_Name << " Age:" << p.m_Age << endl; } //The global function is implemented outside the friend class friend void printPerson2<>(Person<T1, T2> & p); public: Person(T1 name, T2 age) { this->m_Name = name; this->m_Age = age; } private: T1 m_Name; T2 m_Age; }; //1. Global functions are implemented within classes void test01() { Person <string, int >p("Tom", 20); printPerson(p); } //2. Global functions are implemented outside the class void test02() { Person <string, int >p("Jerry", 30); printPerson2(p); } int main() { //test01(); test02(); system("pause"); return 0; }
Summary: it is recommended to implement the global function in class, which is simple to use, and can be directly recognized by the compiler