C++ classes and objects (on)-the basic concepts of classes, class qualifiers and encapsulation and this pointer of class member functions

One, the basic concept of class

1.1 Class definition

class className
{
    
    
// 类体:由成员函数和成员变量组成
}; // 一定要注意后面的分号
  • Class is the keyword to define the class , ClassName is the name of the class , {} is the main body of the class , pay attention to the semicolon after the end of the class definition .
  • The elements in the class are called the members of the class; the data in the class are called the attributes or member variables of the class; the functions in the class are called the methods or member functions of the class .

1.2 Two ways to define a class

  1. Declarations and definitions are all placed in the class body. Note: If a member function is defined in the class , the compiler may treat it as an inline function .
    Insert picture description here
  2. The declaration is placed in the .h file, and the class definition is placed in the .cpp file (usually this way)
    Insert picture description here

Second, the access qualifier and packaging of the class

2.1 Access qualifier

C++ realizes the way of encapsulation: Use classes to combine the properties and methods of the object to make the object more complete, and selectively provide its interface to external users through access permissions .

Insert picture description here
Access qualifier description :

  1. Public modified members can be directly accessed outside the class
  2. Protected and private modified members cannot be directly accessed outside the class
  3. The scope of access rights starts from where the access qualifier appears until the next access qualifier appears
  4. The default access permission of class is private and struct is public (because struct is compatible with C)

Note: The access qualifier is only useful at compile time. After the data is mapped to the memory, there is no difference in the access qualifier

Q1: What is the difference between struct and class in C++?

C++ needs to be compatible with the C language, so struct in C++ can be used as a structure. In addition, struct in C++ can also be used to define classes. It is the same as class which defines the class. The difference is that the default access method of the members of struct is public, and the default access method of the members of class is private.

2.2 Packaging

Q1: Three characteristics of object-oriented

Encapsulation, inheritance, polymorphism.

Q2: In the class and object stage, we only study encapsulation features. What is encapsulation?

Encapsulation: Combine data and methods of manipulating data organically, hide the properties and implementation details of the object, and only expose the interface to the outside to interact with the object.
Encapsulation is essentially a kind of management: how do we manage the terracotta warriors? For example, if nothing is left, the terracotta warriors will be destroyed at will. Then we first built a house to encapsulate the terracotta warriors. But our purpose is all encapsulated and not let others see it. Therefore, we have opened the ticket sales channel, and can buy tickets to break through the package and enter under a reasonable supervision mechanism. The same is true for classes. We use class data and methods to encapsulate them together. Don't want others to see, we use protected/private to encapsulate the members . Open some common member functions for reasonable access to members. So encapsulation is essentially a kind of management.

Three, the scope and instantiation of the class

3.1 Scope of the class

The class defines a new scope , and all members of the class are in the scope of the class. To define members outside the class, you needUse :: scope resolver to specify which class domain a member belongs to

class Person
{
    
    
public:
	void PrintPersonInfo();
private:
	char _name[20];
	char _gender[3];
	int _age;
};

// 这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo()
{
    
    
cout<<_name<<" "_gender<<" "<<_age<<endl;
}

3.2 Instantiation of the class

The process of creating objects with class types is called class instantiation

  1. A class is just a model-like thing, which limits the members of the class, defines a class and does not allocate actual memory space to store it
  2. A class can instantiate multiple objects, the instantiated objects occupy actual physical space, and store class member variables
  3. Make an analogy. Class instantiating objects is like building a house using architectural design drawings in reality. Classes are like design drawings , only designing what is needed, but there is no physical building. The same class is just a design, instantiated Objects can actually store data and occupy physical space
    Insert picture description here

Fourth, the class object model

4.1 How to calculate the size of a class object?

There can be both member variables and member functions in a class, so what is contained in an object of a class? How to calculate the size of a class?

4.2 Guessing the storage method of class objects

  • The object contains each member of the class.
    Insert picture description here
    Disadvantage: The member variables in each object are different, but the same function is called. If stored in this way, when a class creates multiple objects, each object will save a code , Save the same code multiple times, wasting space. So how to solve it?

  • Only the member variables are stored, and the member functions are stored in the common code segment.
    Insert picture description here
    Insert picture description here
    Question: For the above two storage methods, what kind of method does the computer store in?
    Let's analyze and see by obtaining the sizes of the different objects below.

#include<iostream>
using namespace std;

class A1{
    
    
public:
  void f1(){
    
    };
  private:
  int _a;
};
// 类中仅有成员函数
class A2 {
    
    
public:
  void f2() {
    
    }
};
// 类中什么都没有---空类
class A3
  {
    
    };

int main()
{
    
    
  cout<<sizeof(A1)<<endl;
  cout<<sizeof(A2)<<endl;
  cout<<sizeof(A3)<<endl;
  return 0;
}

result
Insert picture description here

4.3 The size calculation conclusion of the class

Conclusion:
The size of a class is actually the sum of the "member variables" in the class. Of course, memory alignment must be performed. Pay attention to the size of the empty class. The empty class is special. The compiler gives the empty class a byte to uniquely identify this class.

Five, this pointer

5.1 Leading out of this pointer

First we define a date class

#include<iostream>
using namespace std;

class Date
{
    
    
public:
  void Init(int year, int month, int day)
  {
    
    
    _year = year;
    _month = month;
    _day = day;
  }

  void Print()
  {
    
    
    cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
  }

private:
  int _year;
  int _month;
  int _day;
};

int main()
{
    
    
  Date d1,d2;
  d1.Init(2021,3,1);
  d1.Print();
  d2.Init(2021,2,28);
  d2.Print();
  return 0;
}

As a result
Insert picture description here
, there are two member functions Init and Print in the Date class. There is no distinction between different objects in the function body. When d1 calls the Init function, how does the function know that it should set the d1 object instead of the d2 object?

C++ solves this problem by introducing the this pointer, that is: The C++ compiler adds a hidden pointer parameter to each "non-static member function", so that the pointer points to the current object (the object that calls the function when the function is running), All member variable operations in the function body are accessed through this pointer. It's just that all operations are transparent to the user, that is, the user does not need to pass it, and the compiler completes it automatically.
Insert picture description here

5.2 Characteristics of this pointer

  1. The type of this pointer: class type * const, the
    following way is wrong
  void Init(Date* this, int year, int month, int day)
  {
    
    
  	//this是隐含的,实参和形参的位置我们不能手动添加会报错
    _year = year;
    _month = month;
    _day = day;
  }

  1. This pointer can only be used inside "member functions"
  void Init(int year, int month, int day)
  {
    
    
    cout<<"this:"<<this<<endl;
    this->_year = year;
    this-> _month = month;
    this-> _day = day;
  }

Insert picture description here

  1. The this pointer is actually a formal parameter of a member function. When an object calls a member function, the object address is passed to the this parameter as an actual parameter. So the this pointer is not stored in the object.
  2. The this pointer is the first implicit pointer parameter of the member function. Generally, it is automatically passed by the compiler through the ecx register and does not need to be passed by the user.

Q1: Where does this pointer exist?

The this pointer is actually a formal parameter of a member function. When an object calls a member function, the object address is passed to the this parameter as an actual parameter. So the this pointer is not stored in the object. In other words, the this pointer exists in the stack, but in order to improve efficiency in vs, the this pointer exists in the ecx register
Insert picture description here

Q2: Can this pointer be null?

We use the following program to analyze

class A
{
    
    
public:
	void PrintA()
	{
    
    
		cout<<_a<<endl;
	}
	void Show()
	{
    
    
		cout<<"Show()"<<endl;
	}
private:
	int _a;
};

int main()
{
    
    
	A* p = NULL;
	p->PrintA();
	p->Show();
	return 0;
}

The above code can be compiled and passed, but p->PrintA() will crash when run separately, but p->Show() can run.
Insert picture description here
Insert picture description here
Reason:
Insert picture description here
Although p is a null pointer, the member functions in the class are stored in the public code segment, not in the object, and p is not dereferenced when calling, so Print will not crash.

Guess you like

Origin blog.csdn.net/qq_40076022/article/details/113999669