4.3 C + + object model and this pointer
4.3.1 member variables and member functions are stored separately
In C + +, member variables and member functions in a class are stored separately
Only non static member variables belong to objects of a class
#include <iostream> using namespace std; // Member variables and member functions are stored separately class Person { int m_A; // A non static member variable is on an object that belongs to a class string m_C; static int m_B; // Static member variables are on objects that do not belong to a class void func() // Non static member functions on objects that do not belong to a class { } static void func2() // Static member functions are not on objects of real classes { } }; int Person::m_B = 100; void test01() { Person p; // The memory space occupied by empty objects is: // The C + + compiler will also allocate a byte space to each empty object to distinguish the memory occupied by empty objects // Each empty object should also have a unique memory address cout << "sizeof p = " << sizeof(p) << endl; } void test02() { Person p; cout << "sizeof p = " << sizeof(p) << endl; } int main() { // test01(); test02(); system("pause"); return 0; }
4.3.2 this pointer concept
Through 4.3.1, we know that in C + +, member variables and member functions are stored separately
Each non static member function will only produce a function instance, that is, multiple objects of the same type will share a piece of code
So the question is: how does this piece of code distinguish that object from calling itself?
c + + solves the above problems by providing special object pointer and this pointer. The this pointer points to the object to which the called member function belongs
this pointer is a pointer implied in each non static member function
this pointer does not need to be defined and can be used directly
Purpose of this pointer:
- When a formal parameter has the same name as a member variable, it can be distinguished by the this pointer
- Return the object itself in the non static member function of the class. You can use return *this
#include <iostream> using namespace std; class Person { public: Person(int age) { // The this pointer points to the object to which the called member function belongs this->age = age; } Person& PersonAddAge(Person &p) { this->age += p.age; // This points to the pointer to p2, and * this points to the object ontology p2 return *this; } int age; }; // 1. Resolve name conflicts void test01() { Person p1(18); cout << "p1 Your age is:" << p1.age << endl; } // 2. Return the object itself with * this void test02() { Person p1(10); Person p2(10); // If the called function returns Person // // p2.PersonAddAge(p1); Age of P2 is modified (P2. Age + = P1. Age) // // p2.PersonAddAge(p1).PersonAddAge(p1); // p2.0 was called first PersonAddAge(p1); Returns a function that copies p2, and then p2 ` PersonAddAge(p1); // // p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1); // p2.0 was called first PersonAddAge(p1); Returns a function that copies p2, and then p2 ` Personaddage (P1), last p2 ` PersonAddAge(p1) // p2 ` and p2 ` ` are newly created functions and will not affect the value of p2 // If the called function returns person& // p2.PersonAddAge(p1); Age of P2 is modified (P2. Age + = P1. Age) // // p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1); Because the returned address is P2, the function call is like this // p2.PersonAddAge(p1); p2.PersonAddAge(p1); p2.PersonAddAge(p1); This is equivalent to P2 calling personaddage (P1) three times // Chain programming idea p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1); cout << "p2 Your age is:" << p2.age << endl; } int main() { // test01(); test02(); system("pause"); return 0; }
4.3.3 null pointer accessing member functions
C + + hollow pointer can also call member functions, but pay attention to whether this pointer is used
If this pointer is used, it needs to be judged to ensure the robustness of the code
Example:
#include <iostream> using namespace std; // Calling a member function with a null pointer class Person { public: void showClassName() { cout << "this is Person class" << endl; } void showPersonAge() { // The reason for the error is that the pointer passed in is NULL // The solution is to judge whether the pointer is empty if (this == NULL) { return; } cout << "age = " << this->m_Age << endl; } int m_Age; }; void test01() { Person* p = NULL; p->showClassName(); p->showPersonAge(); } int main() { test01(); system("pause"); return 0; }
4.3.4 const modifier member function
Constant function:
- After adding const to a member function, we call this function a constant function
- Member properties cannot be modified within a constant function
- After the keyword mutable is added to the member attribute declaration, it can still be modified in the constant function
Constant object:
- Add const before declaring an object to call it a constant object
- Constant objects can only call constant functions
Example:
#include <iostream> using namespace std; // Constant function class Person { public: // The essence of this pointer is a constant pointer. The pointer cannot be modified // const Person* const this; // Add const after the member function to modify the point of this. The value pointed by the pointer cannot be modified void showPerson() const { this->m_B = 100; // this->m_A = 100; // this = NULL; // this pointer cannot be modified } void func() { m_A = 100; } int m_A; mutable int m_B; // For special variables, even in constant functions, you can modify this value and add the keyword mutable }; void test01() { Person p; p.showPerson(); } // Constant object void test02() { const Person p; // Add const before the object to become a constant object // p.m_A = 1100; p.m_B = 100; // m_B is a special value, which can also be modified under constant objects // Constant objects can only call constant functions p.showPerson(); //p.func(); // Constant objects cannot call ordinary member functions because ordinary member functions can modify properties } int main() { system("pause"); return 0; }