Analysis and appreciation of classes and objects in C + + (Part I)

Posted by lives4him06 on Sat, 12 Feb 2022 07:10:20 +0100

1, Process oriented and object oriented

Before learning classes, let's review some connections and differences between C language and C + +:
C language is process oriented, focusing on the process, analyzing the steps of solving the problem, and gradually solving the problem through function call. At the code level, it embodies functions.
C + + is based on object-oriented and focuses on objects. It divides a thing into different objects and completes it by the interaction between objects. At the code level, it reflects the design of classes and the relationship between classes.
In general, C + + is based on object-oriented: a mixture of object-oriented and process oriented (because C + + is compatible with C).

2, Introduction and definition of class

struct class

In C + +, there are two kinds of class representation methods: struct or class; Because struct is upgraded to class in C + +.
Moreover, the structure of C + + class is very different from that in C language. In addition to variables, functions can also be defined in the class.
Examples are as follows:

//In C + +, struct is upgraded to class
//C + + is also compatible with the use of structures in C language
struct Date
{
	//Member variable
	int _year;
	int _month;
	int _day;
	//Member function
	void DateInit(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
};

int main()
{
	struct Date d1; // Compatible c
	Date d2;     // Upgrade to class. Date is the class name and type
	
	return 0;
}

Class class

class ClassName
{
	// Class body: it is composed of member functions and member variables
};

//Class is the keyword defining the class, ClassName is the name of the class,
// {} is the body of the class. Pay attention to the semicolon after the end of class definition.
 
//Elements in a class are called members of the class:
//The data in the class is called the attribute or member variable of the class; 
//Functions in a class are called methods or member functions of the class

Class can be defined in two ways:
① All declarations and definitions are placed in the class body
② The statement is placed in the h file, the class definition is placed in cpp file

3, Access qualifiers for encapsulation and classes

encapsulation

Three characteristics of object-oriented: encapsulation, inheritance and polymorphism.
In the class and object phase, we only study the encapsulation characteristics of classes. What is encapsulation?
Encapsulation: organically combine the data with the methods of operating the data, hide the attributes and implementation details of the object, and only expose the interface to interact with the object.
Encapsulation is essentially a kind of management:
1. Data and methods are encapsulated in classes,
2. You can define your access as public, but you don't want to define your access as private or protected;
Non encapsulation is a free management.

Access qualifier

C + + implementation of encapsulation: combine the attributes and methods of the object with classes to make the object more perfect, and selectively provide its interface to external users through access rights.

Access qualifier Description:
① Members decorated with public can be accessed directly outside the class
② Protected and private modified members cannot be accessed directly outside the class (protected and private are similar)
③ The scope of access rights starts from where the access qualifier appears until the next access qualifier appears
④ The default access permission of class is private and struct is public (because struct is compatible with C)

The difference between struct and class in C + +
C + + needs to be compatible with 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 the class definition class, except that the default access method of struct members is public, and the default access method of class members is private.

4, Scope of class

Class defines a new scope, and all members of the class are in the scope of the class. To define a member outside a class, you need to use the:: scope resolver to indicate which class domain the member belongs to.

class Person
{
public:
	void PrintPerson();
private:
	char _name[56];
	char _gender[2];
	int _age;
};

// Here, you need to specify that PrintPerson belongs to the field of Person
void Person::PrintPerson()
{
	cout << _name << " "<<_gender << " " << _age << endl;
}

5, Class object model

Calculation of class object size

In fact, a class is to create a type that is not available in C + +, that is, a custom type. Like int and char types, this type needs to occupy a certain size in memory. For example, int type takes up 4 bytes and char type takes up 1 byte. How many bytes do we need to take up for our custom type structure?
To understand the size of a class, you must first master the alignment rules of the structure, because the alignment rules of the structure are similar to those of the class:
① The first member is at an address offset from the structure variable by 0.
② The number of times a variable's address is aligned to the number of other members.
Alignment number = the smaller value of the compiler's default alignment number and the size of the member.
The default value in VS2019 is 8
③ The total size of the structure is an integer multiple of the maximum number of alignments (each member variable has an alignment number).
④ If a structure is nested, the nested structure is aligned to an integer multiple of its maximum alignment number, and the overall size of the structure is an integer multiple of all the maximum alignment numbers (including the alignment number of nested structures).

The size of a class is actually the sum of "member variables" in the class. Of course, memory alignment should also be carried out (the same as structure memory alignment). Pay attention to the size of empty classes. Empty classes are special. The compiler gives empty classes a byte to uniquely identify this class.

How class objects are stored

If the object contains all members of the class, 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, a code will be saved in each object, and the same code will be saved multiple times, which wastes space.
Storage method of class object: the object only saves member variables, and member functions are stored in public code segments.

6, this pointer

Let's take a look at a simple date class:

class Date
{
public:
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year; // year
	int _month; // month
	int _day; // day
};
int main()
{
	Date d1, d2;
	d1.Init(2022, 2, 1);
	d2.Init(2018, 1, 16);
	d1.Print();
	d2.Print();
	return 0;
}

For the above date class, there is a problem:
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 Init and Print functions, how does the function know that it should be d1 object instead of d2 object?

This problem is solved by introducing this pointer in C + +, That is, the C + + compiler adds a hidden pointer parameter to each "non static member function" to point to the current object (the object that calls the function when the function runs). All member variable operations in the function body are accessed through the pointer. However, all operations are transparent to the user, that is, the user does not need to pass them, and the compiler completes them automatically

Classic example of this pointer:
Procedure 1:

// 1. Can the following program be compiled?
// 2. Will the following program crash? Where did it collapse
class A
{
public:
	void Show()
	{
		cout << "Show()" << endl;
	}
private:
	int _a;
};

int main()
{
	A* p = nullptr;
	p->Show();
}

Procedure 2:

// 1. Can the following program be compiled?
// 2. Will the following program crash? Where did it collapse
class A
{
public:
	void PrintA()
	{
		cout << _a << endl;
	}
private:
	int _a;
};

int main()
{
	A* p = nullptr;
	p->PrintA();
}

Topics: C++ Back-end