C + + improve programming

1. Programming ideas in c + +
(1) Object oriented programming
(2) Generic programming: it mainly uses technical templates for programming
2. Template
(1) Characteristics
① It can't be used directly. It's just a framework
② The universality of templates is not omnipotent, that is, a template is not used in all occasions
(2) Function template
① The purpose of the template is to improve the reusability of the code, parameterize the type, and determine the specific type when using it

//There are many data types of function templates. If there is no template, you need to write many functions to realize the exchange of two numbers
// The purpose of template is to improve the reusability of code and parameterize types
//Function template
template<typename T>//The typename here can be replaced by class
//Declare a template and tell the compiler not to report an error for the T immediately following the code. T is a general data type
void mySwap(T& a, T& b) {
	T temp = a;
	a = b;
	b = temp;
}
void test() {
	int a = 10;
	int b = 30;
	//Exchange using function template
	//Two ways of use
	1,Automatic derivation type //A consistent data type T must be derived before it can be used
//(the template can only be used after determining the data type T)
	//mySwap(a, b);
	//2. Displays the specified type in angle brackets
	mySwap<int>(a, b);

② For automatic type derivation, a consistent data type T must be derived before it can be used

void test01() {
	int a = 10;
	int b = 20;
	char c = 'c';
	//mySwap(a, c);// Derived T inconsistent, error
	mySwap(a, b);
}

③ The template can be used only after the data type of T is determined

template<class T>
void func()
{
	cout << "func call" << endl;
}

void test02() {
	//func();// Call error, because T is not used in the function, the type of T cannot be deduced
	func<int>();
}

(3) Difference between ordinary function and function template
① Implicit type conversion can occur when calling ordinary functions (as shown in the following example)

//Ordinary function
int myAdd(int a, int b)
{
	return a + b;
}
void test05()
{
	int a = 10;
	int b = 10;
	char c = 'c';
	cout << myAdd(a, c) << endl;
	//Here, two int types are supposed to be passed in, while c is char type, so implicit type conversion will be carried out to render c in its ASCL code
}

② Function template
1) Implicit type conversions cannot occur when deriving with automatic types
2) Implicit type conversion can occur by displaying the specified type (so when using function template, display the specified type)
③ General function and function template calling rules
//1. If both function templates and ordinary functions can be called, ordinary functions shall be called first
//2. The function template can be forcibly called through the empty template parameter list, such as myprint < > (a, B, b);
//3. The function template can be overloaded
//4. If the function template can produce better matching, call the function template first
//(for example, when the data type of ordinary functions needs to be forcibly converted from char type to int type, but the function template does not need it)

(4) Limitations of function templates
//Templates are not omnipotent. For example, self-defined types will not report errors when writing code, but will report errors when running
//Solution: use specific templates (that is, specific for user-defined types) to solve the generalization of user-defined types
//Learning templates is not to write templates, but to use the templates provided by the system in STL

//Template code, not applicable to user-defined type data, because the user-defined type has no definition of = =
 //Solution: 1. Materialize the template class
 //2. Of course, you can overload = =, and define = = under this custom type
template<class T>
bool ifEqual(T a, T b) {
	if (a==b)
	{
		return true;
	}
	else
	{
		return false;
	}
}
//Use the version of materialized Person to realize the code, and materialization takes priority to call
template<>bool ifEqual(Person a, Person b) {
	if (a.m_Name==b.m_Name && a.m_age==b.m_age)
	{
		return true;
	}
	else
	{
		return false;
	}
}
void test08()
{
	Person p1("deng", 11);
	Person p2("deng", 11);
	if (ifEqual(p1, p2))
	{
		cout << "a = b" << endl;
	}
	else
	{
		cout << "a != b" << endl;
	}
}

3. Class template
(1) It's different from the function template, except that there is a class after the template

template<class NameType,class AgeTye>//The same is true for multiple parameters
class Person
{
public:
	Person(NameType name,AgeTye age) {
		this->m_Name = name;
		this->m_Age = age;
	}
	void showM() {
		cout << "full name:" << this->m_Name << endl;
		cout << "Age:" << this->m_Age << endl;
	}
	NameType m_Name;
	AgeTye m_Age;
};

void test01() {
	Person<string, int> p1("deng", 12);
//When creating an object, you need to declare a parameter list, which cannot be derived automatically. You can only display the specified type
	p1.showM();
}

(2) The difference between class template and function template
① Class template has no automatic type derivation
② Class templates can have default parameters in the template parameter list

template<class NameType,class AgeTye=int>//The second parameter uses the default type of the class
class Person
{
public:
	Person(NameType name,AgeTye age) {
		this->m_Name = name;
		this->m_Age = age;
	}
	NameType m_Name;
	AgeTye m_Age;
};
void test01() {
	Person<string> p1("deng", 12);
	//When creating an object, you need to declare a parameter list, which cannot be deduced automatically
	//Class template can use default type, so when declaring parameter list here, the second parameter uses default parameter list
}

(3) When to create member functions in class templates and ordinary classes
① Ordinary classes can be created from the beginning
② Template class: the member function is created only when it is called (so there is a type error in the member function, which can be found only when it is called. If it is called every time, the error cannot be found)
(4) Class template object as function parameter

//Class template object as a function parameter
//1. Specify the incoming type (generally used)
// 2. Parameter Templating
// 3. Whole class Templating
template<class T1,class T2>
class Person1
{
public:
	Person1(T1 name, T2 age) {
		m_name = name;
		m_age = age;
	}
	void showPerson1()
	{
		cout << "full name:" << this->m_name << endl;
		cout << "Age:" << this->m_age << endl;
	}
	T1 m_name;
	T2 m_age;
};
//1. Specifies the type of the incoming parameter
void printMyclass01(Person1<string,int>&p) {
	p.showPerson1();
}
//2. Parameter Templating
template<class T1,class T2>
void printMyclass02(Person1<T1,T2>&p) {
	p.showPerson1();
}
//3. Class Templating
template<class T>
void printMyclass03(T& p) {
	p.showPerson1();
}

void test02() {
	Person1<string,int> p("deng", 12);
printMyclass01(p);
printMyclass02(p);
	printMyclass03(p);
}

(5) Class template and inheritance
//Class template and inheritance
//When the parent class inherited by the subclass is a class template, the subclass should specify the type of T in the parent class when declaring
//If it is not specified, memory cannot be allocated to the subclass (in this way, the T type of the parent element in the subclass is fixed)
//If you want to flexibly specify the T type in the parent class, the child class also needs to be changed into a class template

template<class T>
class Base
{
public:
	T m_obj1;
};
//1. Specifies the type of T in the parent class
class son:public Base<int>
{
};
//2. For flexibility, subclasses are also templated
template<class T1,class T2>
class son1:public Base<T1>
{
public:
	son1(T1 obj1, T2 obj2) {
		this->m_obj1 = obj1;
		this->m_obj2 = obj2;
		cout << typeid(T1).name() << endl;//Type represented by output T1
	}
	T2 m_obj2;
};
void test03()
{
	son1<string,int> s("ren",12);	
}

(6) Out of class implementation of class template member function
//1. Implement outside the class and add the class template declaration, such as template < class T1, class T2 >
//2. Add a parameter list after the scope, such as void person < T1, T2 >:: showperson()
//The above two steps should be added to the implementation outside the class of all member functions, whether or not the parameter is used,
//It is used to declare that this is a member function of the class template, including constructor and destructor

template<class T1,class T2>
class Person2
{
public:
	Person2(T1 name,T2 age);
	void showPerson();
	T1 m_name;
	T2 m_age;

};
template<class T1, class T2>				//Add class template declaration
Person2<T1,T2>::Person2(T1 name, T2 age)	//Add the parameter list after the scope
{
	m_name = name;
	m_age = age;
}
template<class T1, class T2>				//Add class template declaration
void Person2<T1,T2>::showPerson() {			//Add the parameter list after the scope
	cout << "full name:" << m_name << endl;
	cout << "Age:" << m_age << endl;
}

(7) Class template is written in files
① Problem: because the creation time of class template is in the calling stage, it can't be linked when filling in sub files
1) That is, the person is introduced into the call file (. CPP) H, no person is imported cpp
② Solution
1) Import person directly into the calling file CPP, i.e. #include "person CPP ", and person CPP has the function of importing person H (this method is rarely used)
2) Write the declaration and implementation of the template class to the same file, and change the file suffix to hpp, such as person hpp, the suffix is the agreed name and is not mandatory. It is used to represent the name of the template class

(8) Class templates and friends
① It is suggested that the global function (friend) be implemented in class, which is simple to use and can be directly recognized by the compiler
② The implementation of friend functions outside the class is more complex

//Print Person information through global function
template<class T1, class T2>
class Person4;//Since Person4 is used in showPerson, you need to declare Person4 earlier

//2. Out of class implementation of global functions
template<class T1, class T2>
void showPerson(Person4<T1, T2>p) {//Since it is a global function, there is no need to write the scope
	cout << "full name:" << p.m_Name << endl;
	cout << "Age:" << p.m_Age << endl;
}

template<class T1,class T2>
class Person4
{
	1,In class implementation of global functions
	//friend void showPerson(Person4<T1,T2>p) {
	//	Cout < < name: "< p.m_ Name << endl;
	//	Cout < < age: < < p.m_ Age << endl;
	//}

	//2. Out of class implementation of global functions
	// Blank template parameter list
	// If the global function is implemented outside the class, the compiler needs to know the existence of this function in advance
	//friend void showPerson(Person4<T1, T2>p);// This is just a declaration of an ordinary function, which cannot be linked with the implementation of the function template below. An empty parameter list needs to be added
	friend void showPerson<>(Person4<T1, T2>p);//Added empty parameter list
	
public:
	Person4(T1 name,T2 age) {
		this->m_Name = name;
		this->m_Age = age;
	}
private:
	T1 m_Name;
	T2 m_Age;
};
void test06() {
	Person4<string,int> p("feng",12);
	showPerson(p);
}

4. Note:
(1) Prevent shallow copy problems (heap data problems)
① Set copy constructor
② Overload equal sign, operator=

Tags: C++ R & D management

Posted by cbassett03 on Wed, 04 May 2022 06:45:49 +0300