4.3 cpp object model and this pointer
4.3.1 Member variables and member functions are stored separately
In cpp, member variables and member functions within a class are stored separately
Only nonstatic member variables are on objects of a class
#include <bits/stdc++.h> using namespace std; class Person { public: int mA = 0;//Non-static member variables occupy object space static int mB;//Static member variables take up no object space public: void func()//Functions do not take up object space, all functions share one function { cout << "mA:" << this->mA << endl; } //Static member functions also do not take up object space static void sfunc() {} }; int main() { //An "empty" object takes one byte and an int variable takes four bytes cout << sizeof(Person) << endl; return 0; }
4.3.2 this pointer concept
Only one instance of a function is created for each nonstatic member function, that is, multiple objects of the same type share a single piece of code
The question is, how does this piece of code distinguish which object calls itself?
cpp solves this problem by providing a special object pointer, this pointer, which points to the object to which the called member function belongs
The this pointer is a pointer that implies every nonstatic member function
this pointer does not need to be defined, it can be used directly
The purpose of this pointer is:
- When the parameter and the member variable have the same name, the this pointer can be used to distinguish them
- Returns the object itself in a class's nonstatic member function, using return *this
#include <bits/stdc++.h> using namespace std; class Person { public: Person(int age) { //When the parameter has the same name as the member variable, the this pointer can be used to distinguish it this->age = age; } Person& PersonAddPerson(Person p) { this->age += p.age; return *this;//Return the object itself } int age; }; void test01() { Person p1(10); cout << "p1.age = " << p1.age << endl; Person p2(10); p2.PersonAddPerson(p1).PersonAddPerson(p1).PersonAddPerson(p1); cout << "p2.age = " << p2.age << endl; } int main() { test01(); system("pause"); return 0; }
4.3.3 Null pointer access member function
The null pointer in cpp can also call member functions, but it is also important to note if this pointer is used. If this pointer is used, it needs to be judged to ensure the robustness of the code.
Example:
#include <bits/stdc++.h> using namespace std; class Person { public: void ShowClassName() { cout << "I am Person class" << endl; } void ShowPerson() { if (this == NULL) return; cout << mAge << endl; } public: int mAge; }; void test01() { Person* p = NULL; p->ShowClassName();//Null pointer, member function can be called p->ShowPerson();//But if the this pointer is used in a member function, it is not possible } int main() { test01(); return 0; }
4.3.4 const modifies member functions
Constant function
- We call this a constant function after the member function const
- Member properties cannot be modified within a constant function
- Member property declarations can be modified in a constant function after the mutable keyword is added
Constant Object
- Declare an object with const before it is called a constant object
- Constant objects can only call constant functions
#include <bits/stdc++.h> using namespace std; class Person { public: int m_A; mutable int m_B;//Equivalent to a key that can be modified public: Person() { m_A = 0; m_B = 0; } //this pointer is essentially a pointer constant and its pointing cannot be modified //If you want the value pointed to by the pointer to be unmodifiable, you need to declare a constant function void ShowPerson()const { //const Type* const pointer; //this = NULL; //The pointer to Person *const this cannot be modified; //This->m_A=100;//But the data of the object this is pointing to can be changed //const modifies the member function to indicate that the data pointed to by the pointer in the memory space cannot be modified except for the mutable this->m_B = 100; } void MyFunc()const { //m_A = 10000; } }; void test01() { const Person person;//const object cout << person.m_A << endl;//The value of a constant object member variable is accessible but cannot be changed person.m_B = 10;//But common objects can modify the value of mutable-modified member variables person.MyFunc();//Constant objects can only call constant functions } int main() { test01(); return 0; }
4.4 Friends
In your life, there is a living room in your home. All the guests in your Private living room can come in, but your bedroom is Private, which means only you can go in, but you can also allow your friends and friends to go in.
In a program, these private attributes also want special functions or classes outside the class to be accessed. You need to use the technology of friends, which are designed to allow one function or class to access private members in another class.
Keyword friend
Three Representations of Friends
- Global function as friend
- Class as Friend
- Member function as friend
4.4.1 Global Function as Friend
#include <bits/stdc++.h> using namespace std; class Building { //Tell the compiler that the goodGay global function is a good friend of the Buliding class and has access to private content in the class friend void goodGay(Building &building); public: Building() { this->m_SittingRoom = "A living room"; this->m_BedRoom = "Bedroom"; } public: string m_SittingRoom; private: string m_BedRoom; }; void goodGay(Building &building) { cout << "Friends are visiting:" << building.m_SittingRoom << endl; cout << "Friends are visiting:" << building.m_BedRoom << endl; } void test01() { Building b; goodGay(b); } int main() { test01(); return 0; }
4.4.2 Kind of Friends
#include <bits/stdc++.h> using namespace std; class Building;//Here's an advance statement class goodGay { public: goodGay(); void visit(); private: Building *building; }; class Building { //Tell the compiler that the goodGay class is a good friend of the Building class and has access to private content in the Building class friend class goodGay; public: Building(); public: string m_SittingRoom; private: string m_BedRoom; }; Building::Building() { this->m_SittingRoom = "A living room"; this->m_BedRoom = "Bedroom"; } goodGay::goodGay() { building = new Building;//Create building objects } void goodGay::visit() { cout << "Friends are visiting" << building->m_SittingRoom << endl; cout << "Friends are visiting" << building->m_BedRoom << endl; } void test01() { goodGay gg; gg.visit(); } int main() { test01(); return 0; }
4.4.3 member function as friend
#include <bits/stdc++.h> using namespace std; class Building; class goodGay { public: goodGay(); void visit();//Only let the visit function be a good friend of Building to access private content in Building void visit2(); private: Building* building; }; class Building { friend void goodGay::visit(); public: Building(); public: string m_SittingRoom;//Bedroom private: string m_BedRoom;//A living room }; Building::Building() { this->m_SittingRoom = "A living room"; this->m_BedRoom = "Bedroom"; } goodGay::goodGay() { building = new Building; } void goodGay::visit() { cout << "Friends are visiting" << building->m_SittingRoom << endl; cout << "Friends are visiting" << building->m_BedRoom << endl; } void goodGay::visit2() { cout << "Friends are visiting" << building->m_SittingRoom << endl; //Cout << "Friends are visiting"<< building->m_BedRoom << endl;//Not accessible } void test01() { goodGay gg; gg.visit(); } int main() { test01(); return 0; }