[C++] C++ object model and this pointer

1. Separate storage of member variables and member functions

In C++, member variables and member functions in a class are stored separately

Only non-static member variables belong to objects of the class

(1) The size of the empty object

#include <iostream>
using namespace std;

class Person
{
};

void test01() {
	Person p1;
	cout << "空对象的大小是:" << sizeof(p1) << endl;
}

int main(void)
{
	test01();

	system("pause");
	return 0;
}

The memory space occupied by empty objects is: 1; The C++ compiler will also allocate a byte space for each empty object, in order to distinguish the memory location of the empty object;

Every empty object should also have a unique-unique memory address.

#include <iostream>
using namespace std;

class Person
{
public:
	int m_A;     //非静态成员变量  属于类的对象上

	static int m_B;   //静态成员变量 不属于类的对象上

	void func(){}     //非静态成员函数  不属于类的对象上

	static void func2(){}  //静态成员函数  不属于类的对象上
};
int Person::m_B = 10;

void test01() {
	Person p1;
	cout << "p1的大小是:" << sizeof(p1) << endl;
}

int main(void)
{
	test01();

	system("pause");
	return 0;
}

2. The concept of this pointer

We know that member variables and member functions are stored separately in C++

Each non-static member function will only produce a function instance, which means that multiple objects of the same type will share a piece of code

Then the question is: how does this piece of code distinguish which object calls itself?

 

C++ solves the above problems by providing a special object pointer, this pointer. The this pointer points to the object to which the member function is called

This pointer is a pointer that implies every non-static member function

This pointer does not need to be defined, it can be used directly

The purpose of this pointer:

  • When the formal parameter and the member variable have the same name, the this pointer can be used to distinguish

  • To return the object itself in the non-static member function of the class, you can use return *this

(1) When the formal parameter and the member variable have the same name, the this pointer can be used to distinguish

Don't use this

#include <iostream>
using namespace std;

class Person2
{
public:
	Person2(int age)
	{
		age = age;     //编译器会认为这三个age是一样的
	}

	int age;
};

void test02()
{
	Person2 p(18);
	cout << p.age << endl;
}

int main(void)
{
	test02();

	system("pause");
	return 0;
}

Use this

#include <iostream>
using namespace std;

class Person2
{
public:
	Person2(int age)
	{
		this->age = age;    
	}

	int age;
};

void test02()
{
	Person2 p(18);
	cout << p.age << endl;
}

int main(void)
{
	test02();

	system("pause");
	return 0;
}

(2) To return the object itself in the non-static member function of the class, you can use return *this

Now there is a need to always add the age of p1 to p2

#include <iostream>
using namespace std;

class Person2
{
public:
	Person2(int age)
	{
		this->age = age;    
	}

	Person2& addAge(Person2& p)
	{
		this->age += p.age;
		return *this;
	}


	int age;
};

void test02()
{
	Person2 p1(10);

	Person2 p2(10);

	p2.addAge(p1).addAge(p1).addAge(p1);


	cout << p2.age << endl;
}

int main(void)
{
	test02();

	system("pause");
	return 0;
}

3. Null pointer access to member functions

Null pointers in C++ can also call member functions, but also pay attention to whether the this pointer is used

If this pointer is used, it needs to be judged to ensure the robustness of the code

#include <iostream>
using namespace std;

class Person3
{
public:
	void showClass()
	{
		cout << "this is Person3" << endl;
	}

	void showAge()
	{
		cout << "age = " << age << endl;
	}

	int age;
};


void test03()
{
	//空指针访问成员函数
	Person3* p = NULL;
	p->showClass();    //空指针,可以调用成员函数

	p->showAge();      //但是如果成员函数中用到了this指针,就不可以了
}


int main(void)
{
	test03();

	system("pause");
	return 0;
}

Modify the code as follows:

#include <iostream>
using namespace std;

class Person3
{
public:
	void showClass()
	{
		cout << "this is Person3" << endl;
	}

	void showAge()
	{
		if (this == NULL)
		{
			return;
		}
		cout << "age = " << age << endl;
	}

	int age;
};


void test03()
{
	//空指针访问成员函数
	Person3* p = NULL;
	p->showClass();    //空指针,可以调用成员函数

	p->showAge();      //但是如果成员函数中用到了this指针,就不可以了
}


int main(void)
{
	test03();

	system("pause");
	return 0;
}

After testing, static member functions can also be accessed through null pointers.

4. const modified member function

(1) Constant function

Constant function:

  • After the member function is added const, we call this function a constant function

  • Member attributes cannot be modified in constant functions

  • After adding the keyword mutable in the member attribute declaration, it can still be modified in the normal function

#include <iostream>
using namespace std;

class Person4
{
public:


	//1、this指针的本质是一个指针常量,指针的指向不可修改
	//5、如果想让指针指向的值也不可以修改,需要声明常函数
	void show()const    //5
	{
		//3、const Type* const pointer;
		//2、this = NULL; //不能修改指针的指向 Person* const this;
		//4、this->m_A = 100; //但是this指针指向的对象的数据是可以修改的

		//6、const修饰成员函数,表示指针指向的内存空间的数据不能修改,除了mutable修饰的变量
		this->m_B = 100;
	}
	int m_A;
	mutable int m_B; //可修改 可变的
};


int main(void)
{
	

	system("pause");
	return 0;
}
  • The essence of this pointer is a pointer constant, and the pointer's point cannot be modified
  • this = NULL; //Cannot modify the pointer to Person* const this;
  • this->m_A = 100; //But the data of the object pointed to by this pointer can be modified
  • If you want to make the value pointed to by the pointer cannot be modified, you need to declare a constant function;
  • void show()const   {}
  • const modified member function, indicating that the data in the memory space pointed to by the pointer cannot be modified, except for variables modified by mutable

(2) Regular objects

Regular object:

  • Add const before declaring the object to call the object a constant object

  • Constant objects can only call constant functions

#include <iostream>
using namespace std;

class Person4
{
public:


	//1、this指针的本质是一个指针常量,指针的指向不可修改
	//5、如果想让指针指向的值也不可以修改,需要声明常函数
	void show()const    //5
	{
		//3、const Type* const pointer;
		//2、this = NULL; //不能修改指针的指向 Person* const this;
		//4、this->m_A = 100; //但是this指针指向的对象的数据是可以修改的

		//6、const修饰成员函数,表示指针指向的内存空间的数据不能修改,除了mutable修饰的变量
		this->m_B = 100;
	}

	void MyFunc1() 
	{
		
	}

	void MyFunc2()const
	{

	}

	int m_A;
	mutable int m_B; //可修改 可变的
};


void test004()
{
	const Person4 person; //常量对象  
	cout << person.m_A << endl;
	//person.mA = 100; //常对象不能修改成员变量的值,但是可以访问
	person.m_B = 100; //但是常对象可以修改mutable修饰成员变量


	//常对象只能调用常函数
	//person.MyFunc1();   //常对象不可用调用普通成员函数,因为普通成员函数可以修改属性
	
	person.MyFunc2();
}


int main(void)
{
	test004();

	system("pause");
	return 0;
}

 

Guess you like

Origin blog.csdn.net/Zhouzi_heng/article/details/113702802