C++ basic learning update....

Table of contents

anonymous space

 Definition of anonymous space

Cross-file usage of namespaces 

 Allocate dynamic memory space in C language (heap space method)

Use new to allocate heap space and delete to release it in C++

Using new to allocate a two-dimensional array in C++

Summarize the differences between new and malloc

 References in c++

constant reference

Reference as parameter of function

Reference as the return value of a function

Notes on citations:

Function overloading in c++

The principle of c++ function overloading

Notes on function overloading

Classes in c++

Three major characteristics of classes (encapsulation, inheritance, polymorphism)

Constructor in c++ class

destructor

The space size allocation in the class is the same as that of the structure

Copy constructor (key points, difficulties)

Define member functions in a class outside the class

Class inheritance

Inherited syntax

Access permissions for class inherited member properties

Constructors and destructors in inheritance

Hidden issues in classes

Multiple inheritance in classes

Multi-level inheritance in classes

diamond inheritance

virtual function

Overrides in c++

Polymorphism

Implementation conditions for dynamic polymorphism:

virtual destruction 

Pure virtual functions and abstract classes

Friends in c++

friend function

Friend class

Operator overloading

 Two ways of operator overloading

How different operators are overloaded

Templates in c++

What is a template

Template class

 The difference between template functions and template classes

Template class passed as parameter of function

 Member functions of template classes are written outside the class

Inheritance of template classes



anonymous space

Function: Restrict global variables to only be used in the current file

            Tip: Function is similar to static global variables

  Static local variables: 1. Can only be initialized once

                           2. It will change the life cycle of static variables and store them in the data segment.

Static global variable: This global variable can only be used in the current file

 Definition of anonymous space

namespace //If you don’t write the space name, it is an anonymous space.
{
    int a = 100 ; //Fill in the members, variables, functions, and classes in the space
    float b=3.14;
}

Cross-file usage of namespaces 

1. Define the namespace

namespace TX

{

  int a=100;

2. When using the file in the control,

namespace TX

{

    extern int a; //  Declare that the variable a in this space is actually defined externally


 Allocate dynamic memory space in C language (heap space method)

void *malloc(size_t size); //分配大小 为size 的堆空间 

void free(void *ptr);//通过堆空间的首地 址释放该空间

void *calloc(size_t nmemb, size_t size);//分配 nmemb * size 大小的堆空间

void *realloc(void *ptr, size_t size);//把ptr 的堆空间改变大小为size

void *reallocarray(void *ptr, size_t nmemb, size_t size); //把ptr 的堆空间改变大小size*nmemb

Use new to allocate heap space and delete to release it in C++

        数据类型 *变量名 =new 数据类型; //分配一块内存

例如:     int *p=new int ;           /  / 自己计算空间的大小,自己进行类型的转换

                int *p2=new int[100] ;   //分配100块 int类型的堆空间 

                int *q=new int (100);  // 支持分配空间时候对其进行初始化

                int *q=new int (10){1,2,3,7};// 分配度空间进行初始化,其他空间默认为0;

释放对空间:   delete 变量名

例如 :         delete p;

                delete q;

Using new to allocate a two-dimensional array in C++

int main(int argc, char const *argv[])
{    
  int  (*p6)[10]=new int[10][10];
  //p6二维数组赋值
     int x=0;int y=0;
     cout<<"*p6:\n";
    for(x=0;x<10;x++)
    {
        for(y=0;y<10;y++)
        {
            p6[x][y]=x+y;
        }
    }
    
     for(x=0;x<10;x++)
    {
        for(y=0;y<10;y++)
        {
            cout<<p6[x][y]<<"\t";
        }
        cout<<endl;
    }
    cout<<endl;
delete []p6;
}

Summarize the differences between new and malloc

1.new can automatically calculate the size of the data type and type conversion, while malloc can only be performed manually.

2. New can not initialize malloc when reallocating space.

3. When re-allocating the heap space of a class, using new will call the << constructor in the class >>     mallo is not allowed


 References in c++

   Reference: Give a known variable an alias, and the memory will not allocate new space for the reference, saving memory space! !

 The definition syntax of reference: data type & reference name = referenced variable name;

For example:                       int a = 100 ;   // Give an alias for variable a

                                  int & q = a ;     //a and q are completely equivalent! !

The advantage of quoting:         no new variable space will be allocated during the process of passing parameters! ! save space! !

Usage occasions of references : They are generally used to pass as parameters, allowing the function to directly access the data itself, saving temporary space! !

constant reference

Function: 1. Prevent reference names from modifying the value of the original data. 3. Special writing: data type &&reference name;

            2. Reference data constants

             const data type&reference name=referenced object; 

  For example: 1. int a=100; | 2. const int &q=100;

                   const int &p=a; | 3. int &&a=100; //Constant application  

Reference as parameter of function

           When the reference is used as a parameter of the function and the user does not need to modify the data, then we can pass the constant reference!

int  add(const int &a,const int &b)
{
    return a+b;  //并未修改ab 的数据,只是访问 
}

int main()
{
        int a=10,b=20;  
        cout << add(a,b)  << endl;  //可以传递变量  

        cout << add(100,200)  << endl; //也可以传递常量
}

Reference as the return value of a function

 Notice! ! ! !

 1. When a reference is used as a return value, it generally returns: static variables, global variables, heap space, (passed parameter reference)...

 2. When a reference is returned, the function can be used as an lvalue

 3. When a reference is used as the return value, it must be ensured that the space still exists after the function ends! !

Notes on citations:

1. The reference must be initialized (because the reference is an alias, there is no aliased object, where does the alias come from?) 2.
When referencing a constant, you need to use const constant reference or && rvalue reference 
3. The type of the reference must be match    

4. Once the reference is initialized, it cannot be modified again.


Function overloading in c++

1. Using the same function name to define different functions is called function overloading.
2. Overloaded functions are distinguished according to the number and type of parameters.
3. Cannot be distinguished based on return type:

The principle of c++ function overloading

 1. When compiling, the C++ compiler will "automatically check" the "parameter list" of the function written by the user, and alias the function name according to the different parameter lists to generate multiple functions with different names.

2. Automatically deduce the type based on the "parameters" passed in by the user to determine the function to be executed. 

int pf(int a)            / /1.编译器自动别名化  -->  pf_int(int a); 
{
    cout << "打印一个整形数据"  << a << endl; 
    return 0;
}

int pf(char a)            //1.编译器自动别名化 -->  pf_char(char a) 
{
    cout << "打印一个字符数据" << a << endl; 
    return 0;
}

int main()
{
    //一个pf 函数拥有两种不同的功能      
pf(100);                //2.根据传入的参数不同,自动推导调用的函数  100 ->int->pf_int(int a); 
pf('A');               //2.根据传入的参数不同,自动推导调用的函数'A'->char->pf_char(char a) ; 
}
                        //都是c++ 编译器自动去完成的!!不需要用户干预!! 

Notes on function overloading

1. When the function is overloaded, the function name must be the same. 
2. The basis for function overloading is that <number of parameters> <parameter type> are different! 
3. The return value type cannot be used as the basis for overloading!
4. Avoid "ambiguity" when calling overloaded functions     .

5. The default parameter filling order must be from right to left . When calling the function, the order of parameter passing is from left to right .


Classes in c++

Three major characteristics of classes (encapsulation, inheritance, polymorphism)

Encapsulation : 1. Encapsulate the functional function interface into the class

           2. Encapsulate data members into classes

Inheritance : A son inherits something from his father. (Subclasses inherit the function interface or data of the parent class)

            Advantages: Subclasses directly inherit the interface functions of the parent class, without the need to re-develop these interfaces, which improves code reusability and is conducive to software version upgrades.

Polymorphism : An object acts on different things, and the results (functions) obtained are different! !

            Advantages: Improve code reusability

Advantages of object-oriented writing:

1. The code is easy to modify and maintain (because each object is independent and the content of the object only needs to be modified)

2. Improve code reusability (inheritance, polymorphism, function overloading, default parameters) -> ps writes less code

3. Be able to better design complex programs (because many third-party open source libraries are designed using C++. If we want to use these development libraries, we must master the C++ language.) General class definition method:

class 类名 
{
   public:   //共有成员,外界可以访问  
    
   protected:  //保护成员,只有儿子可以访问
    
   private: //私有成员,只有当前类内部可以访问
        
};

//定义一个类的例子: 
class base
{
    public:
        int a; //外界可以访问,因为是共有成员 
    protected: 
         int b;  //子类可以访问,因为保护成员 
    private: 
         int c;  //只有类的内部可以访问 ,因为是私有成员
};

Constructor in c++ class

Constructor : 1. The function name is the same as the class name,
                   2. The function has no return value, 
                   3. The function does not need to be called by the user and is automatically called when the object is created.

class  类名
{
     public:
  	类名()   //构造函数
    {
        
    }   
}
例子: 
    class base
    {
        public: 
         base()
         {
             cout << "调用构造函数" << endl;
         }
    }

Note: 1. The constructor must be written in the public area , because this function will be automatically used when creating an object. If it is not a function in the functional area, it cannot be deleted, causing the creation of the object to fail.

           2. Assuming that the user does not write any constructor , the system will automatically generate a parameterless constructor.

The role of this pointer : used to distinguish internal and external members of a class. Whenever a user creates a class, this class will automatically generate a this pointer, pointing to the first address of the current class!

   base(int a,int b,int c)
     {
         //this->a  当前类-》a 成员
          this->a=a;
          this->b=b;
          this->c=c;
     }
//不使用  this 指针那么  a ,b ,c 变量的名字要重新修改!! 

destructor

Destructor : 1. The function name is the same as the class name, add ~ in front of the function name, 
                  2. The destructor has no return value, "no parameters"
                  3. The system automatically calls when the object is destroyed (the destructor can release the member space )

The role of the destructor : Used to release the data members initialized in the constructor.

 Note: The destructor cannot be overloaded , because the basis for overloading is parameters!

 

The space size allocation in the class is the same as that of the structure

 1. When designing the data members of a class, the data types should be defined in order from small to large . The class defined in this way will occupy the smallest memory space .

 2. The size of the space in the class is only related to the data members in the class and has nothing to do with the member functions in the class.

 3. The size of the empty class is 1

Copy constructor (key points, difficulties)

Shallow copy method automatically generated by the system: Shallow copy ----> Direct assignment

#include  <iostream> 
using namespace std; 
class  base
{
public: 
   //设计一个构造函数 
   base(int a,int b):a(a),b(b){}
void show()
{
     cout << a << endl;
     cout << b << endl;
}
private:
int a; 
int b;
};
int main()
{
         base  a(10,20);
         a.show();
         //通过一个对象去初始化另外一个人对象 
         base b=a;  //系统会自动生成一个浅拷贝构造函数,把a对象的数据赋值给b对象
         b.show(); 
}

Override the system's copy constructor 

When the parameter passed in the constructor is a reference to the class , then the constructor is an overridden copy constructor.

When the user overrides the copy constructor, the system will not automatically generate a shallow copy constructor.

class base
{     public:      base(base &a)     {         cout << "Rewritten copy constructor" << endl;      }





 deep copy  

Why deep copy is needed: The heap memory space after copying is shared.

 

实现深拷贝:
class  base
{
public:
base(const char *str)
{
        //分配p所指向的堆空间 
        p  =  new  char[1024]; 
        //把str数据赋值到堆空间中 
        strcpy(p,str);  
}

//重写拷贝构造函数,实现深拷贝!!!!!
base(base &a)
{
    cout << "调用重写后的拷贝构造函数,实现深拷贝" << endl; 
     //分配p所指向的堆空间  
     p= new  char[1024];  
     //把a空间中的数据拷贝过来  
     strcpy(p,a.p);
}

 void  show()
 {
     cout << "堆空间的地址" << (void *)p << "内容" << p << endl; 
 }
char *p;
};

Define member functions in a class outside the class

函数的返回值   类名::函数的名称(参数列表)
{
    
}
-------------------------------------------
例子: 
class base
{
   public: 
    void show(); //声明 
}; 

//类外定义show 接口
void   base::show()
{
    cout << "show base" << endl; 
}

Class inheritance

Function: 1. Improve code reusability

            2. Conducive to software version upgrades

Inherited syntax

    class class name: inheritance method base class name (parent class name)
{       //fill in the members of the derived class (members of the subclass) 

Access permissions for class inherited member properties

1. Suppose you want to directly access the data members of the base class in the derived class, then the data members of the base class can only be set to shared permissions or protected permissions. 

2. Suppose you want to access the private members of the base class in the derived class. You can only design an interface in the base class to allow the derived class to access indirectly.  

Constructors and destructors in inheritance

 The constructors of both the base class and the derived class will be executed
   The execution order of the constructors: First call the constructor of the base class, then call the constructor of the  
derived class. The destructors of both the base class and the derived class will be executed :
   The execution order of the destructors : First call the destructor of the derived class, and then call the destructor of the base class. 
Summary : In class inheritance, you must handle the constructors and destructors of the base class and the derived class. Allow derived classes to call their own constructors and base class constructors. Otherwise the object cannot be created! 

Hidden issues in classes

1. In inheritance, if a function with the same name appears between a subclass and a parent class, the subclass will hide the function of the parent class.

2. Suppose you want to use the hidden interface of the parent class in the subclass, and use the domain operator to specify whether to use the parent class interface.

a.base::show();

3. In a derived class, as long as you write a function with the same name as the parent class, the methods of the parent class will be hidden. "Overloading is not supported"

It just doesn't support cross-class overloading.

4. Derived classes can also call methods of the parent class by referencing the parent class. base &=new_base //Reference the subclass through the parent class

class  base
{
 public: 
   void show()
   {
         cout <<  "show base" << endl; 
   }
};
//基类 和 派生类出现了同名函数成员。
class  new_base :public base
{
 public:  
  void  show(int a,int b)  //对父类的show 方法进行重载 
  {    
         cout << a << endl; 
         cout << b << endl; 
  }
};
int main()
{
     new_base  a; 
     a.show(); //调用父类的 show 方法 ,无效的调用。因为父类的方法已经被隐藏了
     a.show(10,20); //调用自己的 show 方法 
     //利用域操作符 ,声明是用父类的方法  
     a.base::show(); 

}

Multiple inheritance in classes

         A derived class can inherit multiple base classes and obtain functional interfaces and data members of multiple base classes to improve code reusability.

 class Derived class: inheritance mode base class, inheritance mode base class 2.....

}
Example: 
class base: public base1, public base2      


 The execution order of the constructor: base1 -> base2 -> base The 
 execution order of the destructor: base -> base2 -> base1 
 
//Tip: Whichever one inherits first, then its construction will be executed first, from left to right

Multi-level inheritance in classes

class base class name  
class derived class: inheritance method base class name 
class derived class: inheritance method derived class 

例子: 
class  base 
class  base_a :public base 
class  base_b :public base_a

The execution order of the constructor: base -> base_a -> base_b 
The execution order of the destructor: base_b -> base_a -> base  

diamond inheritance

Note: Diamond inheritance will cause an ambiguity problem, causing the derived class to be unable to call all functions of the base class! !  

1. Use the domain operator to specify which function method in the base class to use 
      a.base_a::show(); 
      a.base_b::show(); 
2. Use the base class to refer to the derived class, and then call it ambiguously The method  
       base_a &q=a; 
       base_b &q=a; 

3. Rewrite the ambiguous method in the derived class and hide the previous one.  
    
4. The strongest method: use virtual inheritance to store the base space in the virtual table without constructing it twice!
base: 
base_a :virtual public base //-> base_a virtual inheritance base -> The system will put base into the virtual table
base_b :virtual public base //->base_b virtual inheritance base -> base_b found that the base already exists in the virtual table Just use it directly without assigning it. 

virtual function

Syntax: 
virtual function return type function name (parameter list) {function body};  
Example: define virtual function 
virtual void func(int,int)
{ } //When a virtual function is defined, the system will generate a virtual table.  
       

 in conclusion:

1. When a class contains a virtual function, the system will automatically allocate a virtual table pointer (*vptr), pointing to the system's virtual table.
2. All user-defined virtual functions are in this virtual table. 
3. The address of the virtual table is always at the front of the object space.
4. Key point "The subclass will inherit the virtual table of the parent class, and the subclass and the parent class share a virtual table" (Conditions for realizing dynamic polymorphism!!)

Overrides in c++

Review of hiding: If a subclass and a parent class have a function with the same name, the subclass will hide the functional interface of the parent class. Assume that if you use the parent class interface, you can reference the parent class and then call its interface.

 Override : When the base class has a virtual function and the virtual function is overridden in the derived class. This is coverage! !

Covered conditions:

1. The base class must have virtual functions 
2. The derived class must override the virtual function of the base class 
3. Point to the derived class through the pointer or reference of the base class and call the overridden method.     
This coverage phenomenon will only occur if the above three conditions are met.  


Polymorphism

What is polymorphism? ?

An object acts on different things, so the results obtained are different. (The status is different)

"A function can achieve multiple different functions! ! !

Function: Improve code reusability.


Static polymorphism: When the program is "compiled", the state to be executed has been determined. -》Function overloading

Dynamic polymorphism: The execution status can only be determined when the program is "running". Depending on the user passing different objects, different states are executed.

Implementation conditions for dynamic polymorphism :

1. The base class must have virtual functions
2. Inherit
3. The derived class overrides the virtual function of the base class 
4. Assign the object of the derived class to the pointer or reference of the base class, and call the overridden interface through the base class.  

#include<iostream>
using namespace std;
class person 
{
  public :
         virtual void zhuangbei()
         {
            cout<<"初始化装备, ";
         }
         virtual void juese()
         {
              cout<<"初始化角色"<<endl;
         }
       virtual  ~person()
         {
               cout<<"person 析构"<<endl;
         }

};
class JC:public person
{
    public:
     virtual void juese()
         {
              cout<<"警察:";
         }
    void   zhuangbei()
    {
        cout<<"手枪"<<endl;
    }   
       virtual ~JC()
         {
               cout<<"JC 析构"<<endl;
         }
} ;
class yisheng:public person
{
    public:
     virtual void juese()
         {
              cout<<"医生:";
         }
    void   zhuangbei()
    {
        cout<<"针"<<endl;
    }   
   virtual ~yisheng()
         {
               cout<<"yisheng 析构"<<endl;
         }

} ;
void set(person *p)
{
        p->zhuangbei();
    p->juese();

    delete p;
}

int main(int argc, char const *argv[])
{
    set(+);
    set(new JC);
    set(new yisheng);
    
    return 0;
}

virtual destruction 

Because the base class pointer is used to release the heap space of the derived class, the system cannot call the destructor of the derived class.

Therefore, it is possible that some data members initialized in the derived class constructor are not released. Causes a waste of resources! !

virtual ~destructor{}  

 virtual ~new_base(){} 

Summary : Regardless of whether the destructor is applied to polymorphic technology, it is best to set it to virtual destructor. Foolproof!  

Pure virtual functions and abstract classes

 Definition of pure virtual function: 
virtual function return type function name (parameter list) =0;
example: 
virtual void func()=0; //Pure virtual function  
abstract class: If there is a pure virtual function in a class, then this class is Abstract class
Characteristics of abstract classes: Abstract classes cannot be instantiated (defined objects)

Function: Design the reserved framework interface of the code and let the derived class implement it. 

Friends in c++

Function: Used to access all data members in the class.

Disadvantages: It destroys the encapsulation of the class, so as a last resort, don't use friends casually.

friend function

Syntax for declaring friend functions:

The return value type of the friend function. Function name (parameter list)  
example: 
friend void show() //This function can access all members in the class in which it is declared 
{ }   

1. When a function is declared as a friend function of a class, the function does not belong to the member function of the class! !

2. Friend functions must be declared within the class!

3. Friend functions can be declared anywhere in the class, regardless of member permissions.

Friend class

Function: When a class is a friend class of another class, the class can access all data members of the other class.

class test{
public: 
  //单纯声明一个接口
 void set_base();
private: 
int c;
//声明 base  是 test 的友元 
friend  class base;
};

class  base{
public: 
//访问 test 中的私有成员
void set_test(){
    test  a; 
    a.c = 100;
}
private: 
int c;
//声明test 是base 的友元 
friend class  test;
};

//重点!!重点!!在base 定义后 才实现  set_base 接口 
void test::set_base()
{
      base  a; 
      a.c = 200;
}

Operator overloading

Function: Give new functions to known operators

The operators learned in the past can only perform basic data type operators, and cannot add two strings, add two classes, or add two structures. At this time, we can use the new operator overloading method in C++ to give operators new functions to perform operations on these data.

 Return type specifier operator operator symbol (<parameter list>) For example: overload the operator     base operator+(base a)    {     }
that adds two base classes   


Overloadable operators:

1. Those operations can be overloaded
: binary operators (+, -, *, /, %) operator+ 
relational operators (==, !=, <, >, <=, >=)
logical operators (||, &&, !)
Unary operators (*, &, ++, --)
Bit operators (|, &, ~, ^, <<, >>)
Assignment operators (=, +=, -=, . ....)
Space application operators (new, delete)
other operators ((), ->, [])
    
2. Those operators cannot be overloaded
. (Member access operator)
.* (Member pointer access operator )
::(field operator)
sizeof(data type length operator)
?:(conditional operator, ternary operator)

 Two ways of operator overloading

 Intra-class overloading method:  
    base operator+(parameter list)  
calling rule: 
   base c = a+b; -> a.operator+(b) is equivalent to this calling method. 
   Features: a is the caller, b is the parameter. Because it is overloaded inside the class, there is this pointer 
       
overloading method outside the class:  
       base operator+(base a, base b) 
       calling rule: 
       base c=a+b; -> operator+(a,b) is equivalent to this Calling method. Characteristics of simple function calls
        : a and b are both parameters in the operator+ function, so this cannot be used 

How different operators are overloaded

1. Relational operators

class base
{
public: 
base(int a):a(a){}
private: 
int a;
friend bool   operator>(base a,base b);
};

//类外重载
bool   operator>(base a,base b)
{
    if(a.a > b.a)
    {
        return true;
    }else{
        return  false;
    }
}

int main()
{

   base a(100); 
   base b(20); 

   if(a > b)
   {
       cout << "a > b" << endl;
   }else{
       cout << "a<b"  << endl;
   }
}

2. Logical operators

class base
{
public: 
base(int a):a(a){}

bool  operator&&(base b)
{
    if(this->a && b.a)
    {
        return true;
    }else
    {
        return false;
    } 
}

private: 
int a;
};

3. Unary operator

class base
{
public:
int a;
base(int a):a(a){}

//++a  先自加,再用值
base operator++()  
{
    cout << "调用++a"  << endl;
    this->a++;  //先自加 
    return *this; //再返回值 
}
//a++  先用值,再自加
base  operator++(int)
{
    cout << "调用a++"  << endl;
    base tmp=*this; //保存原来的值 
    this->a++;

    return tmp;  //先返回值 
}
};
int main()
{
     base a(0);  
     base b=a++;  //先用值,再自加

        cout << b.a << endl; 
        cout << a.a << endl; 
}

4. Overloading of output operators

class  base
{
public: 
base(int a):a(a){}
private:
int a;
friend ostream &operator<<(ostream &out,base a);
};
//类外重载方式
ostream &operator<<(ostream &out,base a)
{
    cout << a.a;

    return out;
}
int main()
{
  
      base a(10086); 
      base b(10010); 
      cout  << a << b << endl;
}

5. Overloading of input operators

class  base{
public:  
base(){}
base(int a):a(a){}
int a;
};
//类外重载输入运算符 
istream &  operator>>(istream &in,base &a)
{
     cin >> a.a;
     return in;
}

int main()
{

     base  a;
     base  b;

     cin  >> a >> b; 

     cout << a.a << endl;
     cout << b.a << endl;

}

Templates in c++

What is a template

A template is a ready-made style that users can apply directly to quickly implement functions.

Templates cannot be used directly and must be instantiated before they can be used.

 Function template: Have a function of a generic type.

General type definition syntax:

template<typename universal type> or template<class universal type>
    
//Example: declare a function with a universal type  
template<class T>   
void show(T a)
{ } //Declare a template function with a universal type For the type T    T, the system will automatically deduce its type based on the parameters passed in by the user. 

template <class T>
void jiaohuan(T &a,T &b)
{
    T c = a; 
      a = b; 
      b = c;
}

int main()
{

   int a=10,b=20; 
   jiaohuan(a,b);
   cout << a << ":"  << b << endl;

   float a1=3.14,b1=4.44; 
   jiaohuan(a1,b1);
   cout << a1 << ":"  << b1 << endl;

   string  a2="hello",b2 ="world"; 
    jiaohuan(a2,b2);
   cout << a2 << ":"  << b2 << endl;
}

1. The difference between template functions and ordinary functions

*Ordinary function calls, automatic type conversion can occur

Automatic type conversion converts low-precision data to high-precision data

char -> short -> int -> float -> double

*Template function call, no automatic type conversion , only automatic type derivation will occur

 2. Calling rules for template functions and ordinary functions

1. When the functions implemented by the template function and the ordinary function are the same, the ordinary function is called first.

2. Assuming that the user does not want to call a normal function, what should be done? ? Use <> to specify a template.

3. When the template function matches the parameters better than the ordinary function, the compiler will give priority to calling the template function.

(The C++ compiler is very smart!!)

4. Template functions also support overloading.

 3. Limitations of template functions

For user-defined data types, template functions cannot operate on the data.

If there are limitations in the template function, special handling will be done under special circumstances! !

#include <iostream>

using namespace std; 

class  base
{
public:  
     base(int a):a(a){}
private:
int a;
//friend  bool   big(base a,base b);
friend  bool   operator>(base a,base b);
};

//重载 base 的比较运算符 
bool operator>(base a,base b)
{
   if(a.a > b.a)
    {
        return true;
    }else
    {
        return false;
    }
}

//设计一个比较两个数据大小的模板 
template <class T>
bool   big(T a,T b)
{
    if(a > b)
    {
        return true;
    }else
    {
        return false;
    }
}

/*
//特殊数据进行特殊处理 
bool   big(base a,base b) 
{

    if(a.a > b.a)
    {
        return true;
    }else
    {
        return false;
    }
}
*/

int main()
{

    base a=100,b=20;
    if(big(a,b))
    {
        cout  << "a > b"  << endl;
    }else
    {
        cout << " a <= b"  << endl;
    }
}

Template class

    When a class has a common data type, then the class is a template class. Template classes cannot define objects before they are instantiated.

 template <class universal type>
class class name 
{     general type variable name };  ---------------------------------- --------- Example:   template <class T> class base {     T a; }; //-> This is a template class








Remember template classes! ! No automatic type inference! The user must manually instantiate it! !

 The difference between template functions and template classes

1. Template classes do not have automatic type deduction function, but template functions do

2. Template classes can use default types

 The default type of template uses:

template <class T=int>
class  base
{
public: 
    base(T a):a(a){}
    void show()
    {
        cout << a << endl;
    }
private:
T a;
};

int main()
{
    base<>  a(3.1415126); //不写类型,则使用上面的默认类型 ,就算添加了默认类型 <> 也是需要填写了
                            //区分该类是一个模板类 
    a.show();
    base<double>  b(3.1415126);  //使用用户指定的模板参数 
    b.show();
    
}

Template class passed as parameter of function

      Note : When a template class is used as a parameter of a function, it cannot be passed directly through the class name as a parameter of the function! !

  Solution:

1. In the parameter list of the function, specify the type of template.   
      void show_base(base<int> a)  
    
2. Continue to template the class parameter type  
template <class T>
void show_base1(base<T> a)
    
3. Directly design the function as a pure template function  
   template <class T>
void show_base2(T a)  

#include <iostream>
using  namespace std;

//这是一个模板类 
template <class T>
class  base{
public: 
base(T a):a(a){}
T a; 
};

class  base1
{
public: 
base1(int a):a(a){}
int a; 
};


//1.指定模板类的参数列表,进行传递
void show_base(base<int> a)
{
    cout <<   a.a << endl;
}

//2.继续把类型模板化 
template <class T>
void show_base1(base<T> a)    //模板函数-》 自动类型推导功能
{
    cout <<   a.a << endl;
}

//3.把该函数设计为模板函数
template <class T>
void show_base2(T a) 
{
     cout << a.a << endl;
}

int main()
{

     base<int>  a(10086); 
      //调用函数 
      show_base(a); 
      show_base1(a);
      show_base2(a);
}

 Member functions of template classes are written outside the class

#include <iostream>

using  namespace std; 

//定义一个模板类 
template <class T>
class base
{
   public:
    //单纯的声明接口
    base(T a); 
   ~base(); 
   void show(); 

private: 
T a;
};

//类外实现这些接口 
template <class T>
base<T>::base(T a)
{
    this->a = a;
}

template <class T>
base<T>::~base()
{
   cout << " base析构函数" << endl;
}

template <class T>
void base<T>::show()
{
    cout << this->a << endl;
}

int main()
{

   base<int>  a(10086); 
   a.show();
}

Inheritance of template classes

       Template classes cannot be directly inherited

Solution:

        1. Specify the template type of the base class

        2. Continue to template the derived class

Guess you like

Origin blog.csdn.net/m0_52467164/article/details/127607261