Templates in C++
1. Friend Functions
Functions have global functions and member functions. If a global function is defined as a friend, it is called a friend global function. If a member function is defined as a friend, it is called a friend member function.
1.1 Friend Global Functions
class Coordinate { friend void printXY(Coordinate& c); public: Coordinate(int x,int y); private: int m_iX; int m_iY; }; void printXY(Coordinate& c) { cout<<c.m_iX<<" "<<c.m_iY<<endl;//Direct access to private members } //usage Coordinate coor(3,5); printXY(coor);
Friend function parameters need to pass an object of this class, its reference, or its pointer, to directly access the object's private or protect its members.
1.2 Friend Member Functions
class Coordinate { friend void Circle::printXY(Coordinate& c);//Declare Circle's printXY function as a Coordinate friend function public: Coordinate(int x,int y); private: int m_iX; int m_iY; }; class Circle { public: void printXY(Coordinate& c) { cout<<c.m_iX<<" "<<c.m_iY<<endl;//Direct access to private members } }; //usage Coordinate coor(3,5); Circle circle; circle.printXY(coor);
By declaring Circle's printXY function as a Coordinate friend function, Circle can directly access Coordinate's private or protected members.However, this breaks the encapsulation of Coordinate, and friends are not recommended unless special needs arise.
2. Friend Classes
You have to declare this class before defining a friend class.
class Circle; class Coordinate { friend Circle;//Define Friend Class public: Coordinate(int x,int y); private: int m_iX; int m_iY; };
This allows you to define a Coordinate object in the Circle class and access its private or protected members arbitrarily.
class Circle { public: void printXY() { cout<<m_coor.m_iX<<" "<<m_coor.m_iY<<endl; } private: Coordinate m_coor; };
This allows any Circle member to access Coordinate members.
Notes for Friends:
- Friend relationship is not transitive
C is the friend of B and B is the friend of A, but C is not necessarily the friend of A, and vice versa. - Friend relationship is one-way
B is the friend of A, A is not necessarily the friend of B - Unlimited form and number of friend declarations
- Friends are just additions to packaging, destroying the packaging and should be avoided as much as possible
3. Static
class Tank { public: Tank(){} ~Tank(){} static int getCount(){return count;}//Static member function static int count;//Static Data Members private: string m_code; }; int Tank::count=0; //Use cout<<Tank::getCount()<<endl; cout<<Tank::count()<<endl; Tank tank; cout<<tank.getCount()<<endl; cout<<tank.count()<<endl;
Static data members do not depend on objects but on classes, that is, the static data member count still exists in memory even if the object is not instantiated, and if it is a normal data member, it must be instantiated to exist in memory.
Since static data members are not dependent on object instantiation, they are not initialized in the constructor; they need to be initialized separately, without the static keyword.
Static members can be accessed through classes and objects.
A static member of an object exists before its data member exists in memory.Ordinary member functions can access static members because they are not object-dependent; static member functions cannot access non-static data members because static members are class-dependent and ordinary members are object-dependent.It's wrong to do something like this:
static int getCount() { m_code="01";//error return count; }
From the point of view of this pointer, ordinary member functions actually have a parameter this pointer, while static member functions do not pass in an invisible this pointer, so they do not know which object's data members are being accessed, so they cannot access non-static members.However, static member functions can access static members.
Notes for static use:
- Static data members must be initialized separately and cannot be written to constructors
- Static member functions cannot call non-static member functions and non-static data members
- Static data members have only one member and exist independent of the object.If sizeof is used to size an object, it does not include static data members
4. Operator overload
The essence of operator overloading is function overloading.Keyword operator, including unary operator overload (-minus sign, ++), only one operand, and binary operator overload
Unary operator overload:
There are two ways, friend function overload and member function overload.
The parameters passed in a friend function overload are the number to the left of the operator, the number to the right of the operator, and the number passed in by a member function overload is the number to the right of the operator, and the current object call
4.1 unary operator overload
4.1.1 Overload-
- Member overloading
class Coordinate { public: Coordinate(int x,int y); Coordinate& operator-();//-overloaded, as a unary operator and member function, without passing any parameters private: int m_iX; int m_iY; } Coordinate& Coordinate::operator-() { m_iX=-m_iX; m_iY=-m_iY; return *this; } //Use Coordinate coor(3,5); -coor;//Equivalent to coor.operator-()
- Friend Function Overload
class Coordinate { friend Coordinate& operator-(Coordinate& coor);//-overload, need to pass parameters, by referencing variables, assign inverse to itself public: Coordinate(int x,int y); private: int m_iX; int m_iY; } Coordinate& operator-(Coordinate& coor) { coor.m_iX=-coor.m_iX; coor.m_iY=-coor.m_iY; return *this; } //Use Coordinate coor(3,5); -coor;//Equivalent to operator-(coor)
4.1.2 Overload+.
- Pre++.
class Coordinate { public: Coordinate(int x,int y); Coordinate& operator++();//Pre++. private: int m_iX; int m_iY; } Coordinate& Coordinate::operator++() { m_iX++; m_iY++;//The value received is the value after ++. return *this; } //Use Coordinate coor(3,5); ++coor;//Equivalent to coor.operator++()
- Post++.
class Coordinate { public: Coordinate(int x,int y); Coordinate operator++(int);//Post++. private: int m_iX; int m_iY; } Coordinate Coordinate::operator++(int) { Coordinate old(*this); m_iX++; m_iY++;//The value received is the value after ++. return old;//Return Old Value } //Use Coordinate coor(3,5); coor++;//Equivalent to coor.operator++(0); a value of 0 is passed in by default, but it does not make sense, it just identifies
The post++ return value is no longer a reference but a Coordinate object, and the parameter is passed in as an int to identify that the current++ is a post-overload. No value needs to be passed in when using it, just an identity.
4.2 Binary Operator Overload
4.2.1 Overload+
- Member overloading
class Coordinate { public: Coordinate(int x,int y); Coordinate operator+(const Coordinate& coor); private: int m_iX; int m_iY; } Coordinate Coordinate::operator+(const Coordinate& coor)//Implicit this pointer to the object to the left of'+' { Coordinate tmp; tmp.m_iX=this->m_iX+coor.m_iX; tmp.m_iY=this->m_iY+coor.m_iY; return tmp; } //Use Coordinate coor1(3,5); Coordinate coor2(4,7); Coordinate coor3(0,0); coor3=coor1+coor2;//Equivalent to coor1.operator+(coor2)
- Friend Function Overload
class Coordinate { friend Coordinate operator+(const Coordinate& c1,const Coordinate& c2);//const can also be written without writing, writing a value that indicates that the addition cannot be modified, is a specification public: Coordinate(int x,int y); private: int m_iX; int m_iY; } Coordinate operator+(const Coordinate& c1,const Coordinate& c2) { Coordinate tmp; tmp.m_iX=c1.m_iX+c2.m_iX; tmp.m_iY=c1.m_iY+c2.m_iY; return tmp; } //Use Coordinate coor1(3,5); Coordinate coor2(4,7); Coordinate coor3(0,0); coor3=coor1+coor2;//Equivalent to operator+(coor1,coor2)
4.2.2 Overload <*
class Coordinate { friend ostream& operator<<(ostream& out,const Coordinate& coor);//The return value must be ostream&and the first parameter must be ostream&out public: Coordinate(int x,int y); private: int m_iX; int m_iY; } ostream& operator<<(ostream& out,const Coordinate& coor) { out<<coor.m_iX<<","<<coor.m_iY; return out; } //Use Coordinate coor(3,5); cout<<coor;//Equivalent to operator<<(cout, coor)
<< Operators cannot be overloaded with member functions because the first parameter of a function must be ostream, not this pointer or current object
4.2.3 Overloaded index operator []
class Coordinate { public: Coordinate(int x,int y); int operator[](int index); private: int m_iX; int m_iY; } int Coordinate::operator[](int index) { if(0==index) return m_iX; if(1==index) return m_iY; //Otherwise throw an exception } //Use Coordinate coor(3,5); cout<<coor[0];//Equivalent to coor.operator[](0) cout<<coor[1];//Equivalent to coor.operator[](1)
The [] operator cannot be overloaded with a friend function because the friend function overloads, the first parameter can be the this pointer in the member function overload or other values, while the first parameter of a [] function overload must be the this pointer in order to pass in an index and express the data members of the current object
5. Function Template
Keyword template typename class
template<class T> T max(T a,T b)//Function Template { return (a>b)?a:b; } //Use int val=max(100,99);//Without specifying the data type T, the computer will choose a template function based on its own judgment char cval=max<char>('A','B'); //Functions produced using function templates are called template functions
If only function templates are written and not used, the computer will not produce any code data. Only when function templates are used, the computer will know what template functions are instantiated.
Variables as template parameters
template<int size> void display() { cout<<size<<endl; } //Use display<10>();
Multiparameter Function Template
template<typename T,typename C> void display(T a,C b) { cout<<a<<" "<<b<<endl; } //Use int a=1024;string s="hello"; display<int,string>(a,s);
Typeename and class can be mixed, for example
template<typename T,class C> T minus(T *a,C b);
It can also be mixed like this
template<typename T,int size> void display(T a) { for(int i=0;i<size;i++) cout<<a<<endl; } //Use display<int,5>(15);
Function templates and overloading
//Mutually overloaded template<typename T> void display(T a); template<typename T> void display(T a,T b); template<typename T,int size> void display(T a); //Use display<int>(10); display<int>(10,10); display<int,5>(10);
6. Class templates
template<class T> class MyArray { public: void display()//Member functions defined within a class {...} private: T *m_pArr; }; //Use MyArray<int> arr; arr.display();
If a member function of a class template is defined outside the class, each function should take the following form:
template<class T> void MyArray<T>::display() {...}
Like function templates, the class template body does not produce substantial code, but only when an object is instantiated, a set of code is generated, called a template class.
Multiparameter Class Template
template<typename T,int size> class Container { public: void display(); private: T m_obj; }; template<typename T,int size> void Container<T,size>::display() { for(int i=0;i<size;i++) cout<<m_obj<<endl; } //Use Container<int,5> con; con.display();
Special note: Template code cannot be compiled separately, that is, it cannot be written as.h file and.cpp file separately, all code should be written in.h file.
7. Standard Template Library STL
7.1 vector
A vector is essentially an encapsulation of an array, and reading can be done in a constant amount of time.
1. Initialization method:
2. Common Functions
Take the traversal method as an example:
vector<int> v; v.push_back(1); for(int i=0;i<v.size();i++) cout<<v[i]<<endl; //Or use an iterator vector<int>::iterator it=v.begin();//:: Mark that the current iterator is a vector iterator for(;it!=v.end();it++)//end() denotes the next element of the last element of the vector, ++ denotes the next element that points to the vector cout<<*it<<endl;//*it denotes the element itself that the iterator points to
7.2 list of chains
Chain list data insertion speed, use the same vectors, push,insert,begin,end,
7.3 Mapping map
map<int,string> m; pair<int,string> p1(10,"p1"); m.insert(p1); m.insert(make_pair(20,"p2")); cout<<m[10]<<endl;
Organize from Muchow c++ Expedition