[C + + template] - class template

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:

  1. Specify the type passed in - displays the data type of the object directly
  2. Parameter templating - changes parameters in an object into templates for transfer
  3. 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

Keywords: C++ Back-end

Added by ajmoore on Sat, 22 Jan 2022 01:44:27 +0200