C++ basic grammar (on classes and objects)

Foreword: The knowledge of C++ grammar is complicated, and there are many details to consider. It is not a good way to learn C++ well from the beginning. The content of books is generally more rigorous, but for beginners, many concepts cannot be understood , You may be hit in the head when you come up. Therefore, it is recommended to learn C language well before learning C++, and then listen to the introductory courses. C++ has many grammatical concepts that are a supplement to C language. After learning C language, you can better understand why it is designed in this way. I am also a beginner. This kind of article written is only for summary of notes and analysis and discussion of some concepts, which is convenient for future recall. Due to limited knowledge, mistakes are inevitable. Welcome to read and advise

 

When I wrote this article on classes and objects, I knew that in order to understand classes and objects, I had to go through a lot of practice. Based on my beginner’s few words, I must be full of mistakes. After thinking about it, I might as well write about beginners. For the understanding of classes and objects, describe the classes and objects in your own eyes, and share your own views, which may provide you with a different perspective. Welcome to advise

Table of contents

The idea of ​​classes and objects

Class and Object Definitions

class access qualifier

Class instantiation and size calculation

this pointer


The idea of ​​classes and objects

If you have learned C language, you will find that if you want to implement a certain project, you must split the project into many small and achievable functions, and then write corresponding functions to realize each small function. The overall combination to realize the project, this is a thought that pays more attention to the process

Because each function has to be implemented manually by yourself, your task is to implement each process. It is conceivable to implement a certain function one by one. The process of realizing the function is also quite complicated

Let's take the realization of daily cooking as an example, the process is like this

On the other hand, C++ adds object-oriented thinking on the basis of C. Object-oriented is to abstract the project to be realized into different objects, and then interact with each other, and finally complete the project. In this process, we pay more attention to Interaction between objects, hiding the tedious detail process

Similarly, we use object-oriented thinking to realize daily cooking

First of all, we abstract different objects according to the cooking items, namely chef, pot, ingredients and condiments, and plates 

Looking at the picture above, with object-oriented thinking, we don’t focus on the specific implementation of each process like process-oriented, but focus on the interaction between abstracted objects, such as the interaction between the above ingredients and the pot and the chef, The interaction between the chef and the plate, and finally the completion of the plate. As for how the chef cooks, when to add water and cover, etc., we don’t think too much about the complicated details.

The author once heard when I was studying the computer group that a high-level language is a layer-by-layer abstraction based on the machine code, so as to hide the complicated details of directly manipulating the hardware, which is somewhat similar to the idea here

Class and Object Definitions

The development of classes in C++ is expanded on the basis of C. When defining a class at the beginning, the structure of C language is still used, but functions can be defined in this structure, and the structure of C language can only define Variables, C++ expands the function of the structure on top of supporting the usage of the C language structure, and develops the class

#include<iostream>

using namespace std;

struct Test
{
	int num1;
	int num2;

	int Add(int x, int y)
	{
		return x + y;
	}
};

int main()
{
	struct Test T;
	T.num1 = 10, T.num2 = 20;
	int tmp = T.Add(T.num1, T.num2);
	cout << tmp << endl;
	return 0;
}

We can use struct to define classes in C++. In order to make a better distinction, C++ provides a new keyword class to define classes. Both of them can be used to define classes, but we still have to get used to using class in the future. Define a class, define a class with class, which is quite similar to the structure in usage

The format of defining a class is class classname class means this is a class, and classname is the class name of the class you want to define

Next, let's define the class of the stack, the name is Stack, don't care about public and private, we will talk about it in detail later

class Stack
{
	
public:

	void StackPush(int x);
	void StackPop();
	int  StackTop();
	bool StackEmpty();

private:

    int* _pos;
	int _size;
	int _capacity;
};

The above is a simple definition of a stack class, and put the variable data and behavior functions required by the stack into the stack. The variables in the class are called member variables or attributes of the class, and the functions in the class are called member functions or methods of the class. . Above we just declared the functions in the class. Of course, we can define these functions in the class, but in this case, the whole class looks bloated, which is not conducive to reading, so we generally define the functions in the function implementation file , but there are many functions defined in the function implementation file, how do I know whether the defined function belongs to a certain class? 

C++ uses the classname :: domain specifier to indicate that a function belongs to the class domain of classname. Let's take a look at two ways to define member functions of a class through a piece of code

定义方法1 类的成员函数定义在其他文件里


void Stack::StackPush(int x)
 {
	 if (_size == _capacity)
	 {
		 int newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
		 int* tmp = (int*)realloc(_pos, sizeof(int) * newcapacity);
		 _pos = tmp;
		 _capacity = newcapacity;
	 }
     
	 _pos[_size++] = x;
 }



 void Stack::StackPop()
 {
	 if (_size <= 0)
		 return;
	 _size--;
 }



 int Stack::StackTop()
 {
	 if (_size <= 0)
		 std::cout << "Stack Empty" << std::endl;
	 return _pos[_size-1];
 }



 bool Stack::StackEmpty()
 {
	 if (_size <= 0)
		 return true;
	 return false;

 }




定义方法2 在类的成员函数定义在类的内部

class Stack
{
	
public:


void StackPush(int x)
 {
	 if (_size == _capacity)
	 {
		 int newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
		 int* tmp = (int*)realloc(_pos, sizeof(int) * newcapacity);
		 _pos = tmp;
		 _capacity = newcapacity;
	 }
     
	 _pos[_size++] = x;
 }



 void StackPop()
 {
	 if (_size <= 0)
		 return;
	 _size--;
 }



 int StackTop()
 {
	 if (_size <= 0)
		 std::cout << "Stack Empty" << std::endl;
	 return _pos[_size-1];
 }



 bool StackEmpty()
 {
	 if (_size <= 0)
		 return true;
	 return false;

 }

It should be noted that the member function defined inside the class may be treated by the compiler as an inline function

class access qualifier

When introducing the definition class, we mentioned public and private. Next, I will explore what these two keywords are. Let me talk about the conclusion first. These two keywords are the access qualifiers of the class. From the literal meaning, you may guess that this has something to do with privacy. Simply put, it is equivalent to a lock, which locks things you don’t want to show you, and makes things public if you want to show them.

Take the stack defined by the class before as an example. The member variables in it record the size of the stack and the number of elements in the stack. This data cannot be changed randomly. In case someone accidentally modifies it when accessing the members of the class The member variables in the class were deleted. There were only 10 elements in the original stack, and it became 20 after changing it. This will cause the entire stack to crash.

Therefore, when we define a class, we hope that some members are protected and are not allowed to be accessed by users. At this time, we can use the keyword private to modify these members, indicating that these members are protected, and cannot be accessed outside the class. visit these members

The members modified by public can be directly accessed outside the class, such as member functions such as popping, pushing, and viewing the top element of the stack.

Scope of access qualifiers:

Access scopes start at the occurrence of this access qualifier until the next occurrence of the access qualifier

If there is no access qualifier, the scope is at the end of the block, }, and the class ends

Only the members of this class can use the members modified by private, out of the class, they cannot be directly accessed

As mentioned before, both struct and class of C++ can define classes. One of the differences between these two definition methods is reflected in the access qualifier. If the access qualifier is not explicitly given, the class defined by struct will have its members default All are public, that is, public. For a class defined by class, its members are all private, that is, private and protected by default.

Class instantiation and size calculation

Class is a self-defined type. When defining a class, it is equivalent to drawing a design diagram. It has no entity and does not occupy memory. Its member variables are undefined, which is very similar to struct , only when a class is created, the class will be instantiated, the member variables in the class will be created, and the actual memory space will be occupied

How to calculate the memory size occupied by that type? Functions and variables can be defined in a class. Presumably, the space occupied by a class should not be small , but this is not the case. The actual size of a class is only related to the size of the member variables in the class, because the member functions in the class do not exist. In the class, there is a public code area. The memory allocation of member variables in the class must also abide by the memory alignment rules. If you forget, you can review the memory alignment rules of the structure in the C language. The calculation of the size of the class is the same, here I won't repeat it

this pointer

Maybe you still have questions about the definition of the above class, for example, why do I add a '_' in front of the definition of the member variable in the class? Also, why can you directly manipulate the stack without passing the pointer when defining the crew function? C language needs to pass the pointer, otherwise there is no way to operate it. How does C++ do it? The entire stack can be manipulated without passing the pointer? ? This is the this pointer we are going to understand next

In fact, C++ does not need to pass the pointer, but hides the pointer in the parameter. Because when the C language implements the stack, every function has to pass the pointer. It is very troublesome to write by hand. C++ will pass the pointer To hide it, the name of this pointer is this pointer

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), and all "member variable" operations in the function body, All 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

The type of the this pointer is the type of the class, and the this pointer is modified by const and cannot be changed

The this pointer is essentially the formal parameter of the "member function". When the object calls the member function, the object address is passed as the actual parameter to the
this formal parameter, so the this pointer is not stored in the object.
This pointer is the first implicit function of the "member function". Included pointer parameters are generally passed automatically by the compiler through the ecx register and do not need to be passed by the user

The text may not be very easy to understand, you can look at the picture below

 

The above example can help us better understand the instantiation of the class and the this pointer. The first program can run normally. Although the pointer P of the class is a null pointer, the function is not stored in the class. P calls function, it will go to the public code area to call the function, there is no dereferencing, it does not matter whether it is a null pointer or not

But the second program will not work, the program will crash midway, because the member variable _a is stored in the class, when P calls the function, the compiler will pass the address of P to the this pointer, and then the this pointer will be dereferenced _a, the this pointer at this time is a null pointer, of course dereferencing cannot occur, so the program crashes

Guess you like

Origin blog.csdn.net/m0_61350245/article/details/127147535