class
Class is used to implement function encapsulation
Class is used to describe "object". Class includes attributes and behavior. For example, the same person is a class. Attributes include people's character, character, appearance, etc. People's action performance belongs to class behavior (behavior is generally a function). A specific person is an instance of a class - an object.
A class is a template for an object, and an object is an instance of a class.
Class is a logical entity that encapsulates data and the code that operates on it
Class has three permissions:
Public permission: it can be accessed outside the class and within the class
Protected permission: it can not be accessed outside the class, but can be accessed inside the class, which is visible to derived classes
private permission: it cannot be accessed outside the class, but can be accessed inside the class
class Class name { //Public access rights public: //Properties and behavior //Protect access protected: // Properties and behavior //Private access private: //Properties and behavior };
The difference between class and struct is that the default permissions are different
If the attribute of a member is not declared in a class, it is private by default
In struct, the default is public
this pointer
The member function of the class can access the data of the class itself, so how to know which object's data is to be operated by the member function?
Access your address through the this pointer, which points to the object to which the called member function belongs
For example, student.show(); Then the student is the object and the this pointer points to it
this is a pointer to access a member variable or member function with - > instead.
Note: this pointer is not a part of the object. The memory occupied by this pointer will not be reflected in the sizeof operator.
This is actually a formal parameter of the member function. When calling the member function, the address of the object is passed to this as an argument. However, this parameter is implicit. It does not appear in the code, but is silently added to the parameter list by the compiler at the compilation stage.
1. The type of this pointer depends on the member function type using this pointer and the object type
2. this pointer can only be used in member functions, not global functions or static functions
The first parameter of the member function is T* const register this by default.
Returning * this means returning the object itself
3. This can only be used inside a class. Through this, you can access all members of the class, including private, protected and public attributes
const keyword
const function
cosnt modified member function: const member function can use all member variables in the class, but cannot modify their values. This measure is mainly set to protect data.
Constant member functions need to add const keyword at the end of the function header when declaring and defining
const object
Const can also be used to modify objects, called constant objects. Once an object is defined as a constant object, you can only call const members of the class (including const member variables and const member functions)
Static member
Static member variable
Static members should be declared inside the class and initialized outside the class.
Static member variables do not belong to any object. Static member variables are shared by all objects of the class
Only one static member variable is stored for all objects to share, so its value can be shared among all objects. Using static member variables to realize data sharing among multiple objects will not destroy the principle of hiding, ensure security and save memory.
class A { public: static int a;//Static member variable declaration means adding static before the data type of the variable }; int A::a = 0; int main() { A temp0; temp0.a = 5;//Static member variables need to be defined, that is, allocate space for static member variables A temp1; cout << temp0.a << endl; cout << temp1.a << endl; } //The output of both lines is 5, indicating that the static member variables are shared
Static member variables can be modified in the const function
The cosnt function is used to protect all ordinary member variables of the object calling the const function (that is, the object pointed to by this pointer) so that they cannot be modified. However, static member variables do not belong to any object, so they can be modified.
class A { public: static int a; int b; void changea(int i) const { this->a = i;//The this pointer accesses the static member variable a } }; int A::a; int main() { A temp0; temp0.changea(6); }
Static member function
, a static member function also belongs to a class, and it does not belong to any object. Static member functions cannot access non static member variables in this class, because non static member functions can be called only after the class object is established. Therefore, in c + +, the main function of static member function is to access static member variables
class A { public: static int a; int b; //Add static before the function to declare the function as a static member function static void showa(){ cout << a << endl; } /*static void showb() { cout << b << endl; }*/ //This annotated code will report an error }; int A::a = 9; int main() { A temp0; temp0.showa(); }
Friends
Friends provide a mechanism for ordinary functions or class member functions to access private or protected members in another class. That is, there are two forms of friends: friend functions and friend classes
Advantages: it improves the operation efficiency of the program.
Disadvantages: class encapsulation and data transparency are destroyed.
friend function
A normal function accesses private or protected members of a class. Declare in any region of the class and define outside the class
Format: friend type friend function name (parameter);
Friend class
Friend class < friend class name >;
- Unidirectionality: Class A declares that class B is its friend, and B can use the private member of a; However, a is not a friend of B and cannot use the private member of B.
- Friends cannot be inherited: Class A declares that class B is its friend, and a's son (inherited from a) and B are not friends.
- Friends are not transitive: Class A is a friend of B, class B is a friend of C, but C is not necessarily a friend of A.
For example, the following statement indicates that class B is a friend class of class A:*
class A
{
...
public:
friend class B;
...
};
After the above description, all member functions of class B are friend functions of class A and can access private and protected members of class A.
Object initialization and cleanup
Constructor
The main function is to initialize the member properties of the object when creating the object,
The initialization process of its object is controlled by one or several special member functions
Always used with the new operator
Syntax: class name () {}
1. Constructor, no return value, no void
2. The function name is the same as the class name
3. Constructors can have parameters and can be overloaded
4. When the program calls the object, it will automatically call the constructor without manual call, and it will only be called once
Classification and calling of constructors
1. Classification
Classification by parameters: parametric construction and nonparametric construction
Classification by type: common construction and copy construction
Copy constructors are commonly used to:
- Initialize the newly created object by using another object of the same type.
- Copy the object and pass the object as a parameter to the function to use all the properties of the object.
- Copy the object and return it from the function.
Format: classname (const classname &obj){
/ / body of constructor
}
2. Call
(1) Bracket method
person p1;//Default constructor call (Note: do not use parentheses when calling the default constructor, because the compiler will recognize it as a declaration) person p2(10);//Parameterized constructor call person p3(p4);//Copy constructor call
(2) Display method
person p1 = person(10);//Constructor call with parameters. It is essentially an anonymous object. The anonymous object will be released after the current execution person p2 = person(p1);//Copy constructor call. (do not initialize anonymous objects with copy constructors)
(3) Implicit construction
person p1 = 10;//Equivalent to person p1(10) person p2 = p1;//Equivalent to person p2(p1)
Shallow copy and deep copy
Shallow copy: a simple assignment operation provided by the compiler
Deep copy: open up a new space in the heap for copying.
Differences between the two:
If only the attribute value of the object is copied, there is no difference between shallow copy and deep copy. The original object will be copied to produce a new object. Modifying the value in the new object will not affect the original object. The new object is completely separated from the original object.
If the elements in the copied object contain references (for example, if another list is stored in a list, the references in another list are stored), the shallow copy is different from the deep copy. Although the shallow copy copies the original object, it still saves the references. Therefore, modifying the values in the references in the new object will still change the values in the list in the original object, The new object is not completely separated from the original object. Unlike deep copy, it will create a new reference in the original object, that is, create a new list, and then put the reference of the new list, so that the new object can be completely separated from the original object
Therefore, shallow and deep copies are only for reference types
Destructor
The main function is that the system automatically calls and performs some cleaning work before the object is destroyed.
Syntax: ~ class name () {}
1. Destructor, no return value, no void
2. The function name is the same as the class name
3. Destructors cannot have arguments
4. The destructor will be called automatically before the object is destroyed. There is no need to call it manually, and it will only be called once
Operator overloading
Redefine the existing operator j and give it another function to adapt to different data types
Overload + operator
For example, there are two attributes m in a class_ A and m_B. When you create two members and add them
Class member function person operator + (person &p). One of the member attributes should be accessed by using the this pointer
Global function person operator + (person & P1, person & P2)
The difference between class member functions and global functions is that one is object-oriented and the other is process oriented
class person { public: int m_A; int m_B; person operator+(person &p)//Overloading through member functions+ { person temp; temp.m_A = this->m_A + p.m_A;//Use the this pointer to access the properties of a1 temp.m_B = this->m_B + p.m_B; return temp; } }; //Overloading through global functions+ person operator+(person &p1, person &p2) { person temp; temp.m_A = p1.m_A + p2.m_A; temp.m_B = p1.m_B + p2.m_B; return temp; } person a1, a2; a1.m_A = 5; a2.m_A = 5; a1.m_B = 10; a2.m_B = 10; person a3 = a1 + a2;//Add two members
Overload < < operator
Function: direct output member function
Create global function ostream & operator < < (ostream & cout, person & P)
#include <iostream> using namespace std; class person { public: int a; int b; }; //Using a reference is an alias. It will not open up new memory space and will not release the returned object ostream &operator<<(ostream &cout, person &p)//The return type of cout is ostream { cout << p.a << " " << p.b;//Chain thought return cout; } int main(void) { person m; m.a = 10; m.b = 12; cout << m << endl; system("pause"); return 0; }
Overloading + + operators
Make members complete + + operations.
#include <iostream> using namespace std; class box { friend ostream &operator<<(ostream &cout, box myprint); //Friends public: box() { a = 0; } //Pre + +, increment first, and then return members box &operator++() { a++; return *this; //The purpose of returning a reference is to increment a data all the time } //Post + +, record first, then increment, and return the recorded value box operator++(int) //int is a placeholder parameter and a function overload occurs { box temp = *this; a++; return temp; //The local variable is released after the current function is executed. It cannot return a reference and needs to return a value } private: int a; }; //Overload < < operator ostream &operator<<(ostream &cout, box myprint) { cout << myprint.a; return cout; } //Post increment void text01() { box m; cout << m++ << endl; cout << m << endl; } //Pre increment void text02() { box m; cout << ++m << endl; cout << m << endl; } int main(void) { text01(); text02(); system("pause"); return 0; }
Overload = operator
For classes with attributes pointing to the heap, there will be shallow copy and deep copy problems.
For shallow copies (error example)
//Shallow copy error example //Purpose: copy m to n #include <iostream> using namespace std; class box { public: box(int age) { A = new int(age); } ~box()//Destructor { if (A != NULL) { delete A; A = NULL; } } int *A; //The properties in the class are in the heap }; void text01() { box m(18); box n(20); n = m; cout << *m.A << " " << *n.A << endl; } int main(void) { text01(); system("pause"); return 0; }
An error will occur in this state because of the destructor. During the destructor, the heap area of n will be cleared first, and then the heap area of M will be cleared. Due to the shallow copy, members m and N share the same block of memory, which has been cleared twice, the program has an error.
**Solution: * * using the idea of deep copy, overload the assignment operator to open up another heap area for member n, so that the heap areas of the two members are independent of each other.
The implementation is as follows:
#include <iostream> using namespace std; class box { public: box(int age) { A = new int(age); } ~box() { if (A != NULL) { delete A; A = NULL; } } box &operator=(box &p) { //First judge whether there are attributes in the heap. If so, clear them first if (A != NULL) { delete A; A = NULL; } A = new int(*p.A);//Reopen a heap for n return *this;//Chain programming idea to realize continuous copy } int *A; //The properties in the class are in the heap }; void text01() { box m(18); box n(20); n = m; cout << *m.A << " " << *n.A << endl; } int main(void) { text01(); system("pause"); return 0; }
Overloading relational operators
#include <iostream> #include <string> using namespace std; class person { public: person(string name, int age) { this->age = age; this->name = name; } //Overload = = operator bool operator==(person &p) { if (this->age == p.age) return true; else return false; } //Reload= operator bool operator!=(person &p) { if (this->age != p.age) return true; else return false; } string name; int age; }; void test01() { person p1("Tom", 18); person p2("Tom", 19); if (p1 == p2) cout << "same" << endl; if (p1 != p2) cout << "no" << endl; } int main(void) { test01(); system("pause"); return 0; }
Overload () operator (functor)
() is called a function call operator
Imitation function is flexible and has no specific writing method
#include <iostream> #include <string> using namespace std; //A functor is not a function but a class class person { public: //Copywriting output function void operator()(string s) { cout << s << endl; } }; void test01() { person myprint; myprint("hello world"); person()("hello world");//Creates an anonymous function object when the specified object is not created } int main(void) { test01(); system("pause"); return 0; }