[Road to Advanced C++] Classes and Objects (Part 1)

1. Object-oriented and process-oriented

  • Object-oriented: It is one of the software development methods. It is a method of understanding and abstracting the real world; it is a relatively advanced method of thinking about problems . When we are object-oriented, we will create objects and mainly care about the behavior of the objects.
  • Process-oriented: Analyze the steps required to solve the problem , and then use functions to implement these steps step by step . When using them, just call them one by one. It is a basic way of thinking about problems.

  • We use the realization of a braised pork dish to reflect the difference between process and object.
  • Process-oriented: 1. Buy meat, cut it, 2. Heat the pot, heat oil, adjust the color of sugar, 3. Put it in the pot, add seasonings to taste, 4. Finish and serve.
  • Target audience: 1. Buy the braised pork , 2. Put the braised pork in the pot , 3. Take out the braised pork
  • Therefore: object-oriented development is more convenient and efficient, while process-oriented development is more cumbersome.

The object-oriented process pays more attention to objects and is more efficient, but sometimes we still need to implement functions ourselves.

2. Introduction of classes - structures

  • Class definition: class + class name + { };
  • In C++, structures are upgraded to classes, but C language usage can still be used .

  • prove:
struct student
{
    
    
	char _name[6];
	int _age;
	int _number;
	student* _p;
};
  • The structure here has been upgraded to a class. In C++, class names can be used to define variables, but not in C language. Of course, if you want to use C language syntax here, you can.
  • Note: In order to distinguish the definition of variables from function call variables , we generally add _ in front of the variables.

  • Functions can be defined in classes
struct student
{
    
    
	void Print()
	{
    
    
		cout << "Print" << endl;
	}
	char name[6];
	int age;
	int number;
	student* p;
};

  • A class is treated as a domain called a class domain
  • The domains of C++ we have learned so far - global domain, local domain, namespace domain, class domain.

3. Class definition

  • Similar to structure: class + class name + {};
  • Note: ;——The semicolon cannot be omitted

1. Two ways of defining a class

Define functions inside the class

class student
{
    
    
	void Print()
	{
    
    
		cout << "Print" << endl;
	}
	char _name[6];
	int _age;
	int _number;
	student* _p;
};

Define functions outside the class - class domain

void student::Print()
{
    
    
	cout << "Print" << endl;
}
class student
{
    
    
	void Print();
	char _name[6];
	int _age;
	int _number;
	student* _p;
};
  • Note: To define a function outside a class, you need to declare the function inside the class , and add the class name + scope qualifier before the function name when defining to indicate that this is a function of this class.

2. Access qualifier

  • public: public - can be directly accessed outside the class
  • private: private - not directly accessible outside the class
  • protector: similar to private - cannot be directly accessed outside the class (will be used in inheritance)

  • Notice
  • 1. In order to be compatible with C syntax, C++ makes the members of the structure class public by default . But in a class, the default members are private and cannot be accessed directly from outside the class .
  • 2. Its scope starts from its occurrence and ends when the next access qualifier/class scope is encountered.
  • 3 The access qualifier is only useful during compilation. It is a syntax check, so an error is only reported during compilation. When the data has been loaded into the memory, the access qualifier is actually the same. The access qualifier is more like A threshold, a premise.

3. Encapsulation - the three major characteristics of object-oriented

  • Encapsulation: Organically combine data and methods of operating data, hide the properties and implementation details of the object, and only expose the interface to interact with the object.
  • Description: Hiding the properties and implementation details of the object is achieved through private. External interface - implemented functions.
  • Encapsulation is to better manage and protect data and avoid data damage. Because the interface will be called to manage data, the interface here is the rule we set . And the interface is generally public .

4. Instantiation of classes

  • Defining a class is like defining a structure . It is similar to the custom type of the structure. When we define the class, we only describe the content in the class and cannot directly use the content of the class . That is the same as defining a structure variable. Instantiation of the same kind .
  • This also indirectly reflects that not all variables in the domain are necessarily definitions, but may also be declarations of variables.
class student
{
    
    
public:
	void Print();
private:
	char name[6];
	int age;
	int number;
	student* p;
};
int main()
{
    
    
	student A;//这样我们就完成了类的实例化。
	return 0;
}

4. Class object model

Find the size of a class

  • Similar to finding the size of a structure:

1. The first member is at the address offset 0 from the structure variable.

2. Other member variables should be aligned to addresses that are integer multiples of a certain number (alignment number).

Description: Alignment number = the smaller of the compiler's default alignment number and the size of the member.

3. The total size of the structure is an integer multiple of the maximum alignment number (each member variable has an alignment number).

4. If a structure is nested and the nested structure is aligned to an integer multiple of its own maximum alignment number, the overall size of the structure is an integer of all maximum alignment numbers (including the alignment number of nested structures) times.

  • What we need to pay attention to is that in C language, at least one variable is defined in the structure, but in C++, the structure is upgraded to a class, which can be empty, and even functions can be defined inside.
  • Does the function occupy memory?

Experiments show:

class student1
{
    
    
public:
	void Print()
	{
    
    
		cout << "Print" << endl;
	}
private:
	int age;
};
class student2
{
    
    
public:
	void Print()
	{
    
    
		cout << "Print" << endl;
	}
};
class student3
{
    
    

};
int main()
{
    
    
	cout << sizeof(student1) << endl;
	cout << sizeof(student2) << endl;
	cout << sizeof(student3) << endl;
	return 0;
}

Insert image description here

  • Comparing student2 and student3 can illustrate that the function does not occupy space in the class.
  • Where is the space occupied by the function? ——Public code segment (when executed, the code that calls this function can be executed)
  • Note: The functions called by different objects are the same.

Insert image description here
Insert image description here
Note: This design is to save space. The functions called by different objects are the same. Just execute the function code when calling. In this way, one code can be used for multiple purposes to save space.

  • Comparing student1 and student2 can simply illustrate that the alignment is consistent with the alignment of the structure.
  • The size of student3 is 1 - indicating that the minimum size of the class is 1. As for why it cannot be 0, assuming that if it is 0, the space allocated is 0. From previous studies, we can know that the allocation of a variable must have an address, 0 space There is no address and it contradicts each other , so it cannot be 0. The 1 here acts as a placeholder.

5.this pointer

C++ solves this problem by introducing the this pointer, that is: the C++ compiler adds a hidden pointer
parameter current object (the object that calls the function when the function is running) , all operations on member variables 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, the compiler automatically completes it.

Basic understanding

class Date
{
    
    
public:
	void Print()//括号里面相当于(this),这里的this也是不能写出来的,也是隐式转换
	{
    
    
		cout << _year <<"-"<< _month<<"-" <<_year<< endl;
		//在函数里面可以使用this指针,上面的代码写完整就是
		cout <<this-> _year <<"-"<<this-> _month<<"-" <<this->_year<< endl;
		//this=NULL 这也是不行的,因为this指针是一个const修饰的类型,不能进行修改。
		//说明定义一个变量int * const this,const具有就近原则
		//放在this前this本身不能修改
		//放在*前说明*this不能被修改
	}
	void Init(int year = 1 ,int month =1,int day = 1)
	{
    
    
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _day;
	int _month;
	int _year;
};

int main()
{
    
    
	Date A;
	A.Init();
	//A.Init(this);这样写是不对的,因为this是隐式转换的,这里的this转换为A的地址;
	//A.Init(&A);其实就转换为了指定对象的地址,怎么进行转换呢?A.这里通过A就能找到A的地址。
	A.Print();
	return 0;
}
  • Let's look at the function call here. Why can we directly use the variables in the class without passing the address of the class variable?
  • Explanation: There is a this pointer implicit here, so what is this pointer?
  • In fact, the this pointer here is the address of the class instantiation.
  • Summary: The this pointer cannot display the parameters passed, nor can the parameters defined by the function be displayed . Variables of the access object can be used inside the function, but the this pointer cannot be modified .

Code interpretation

struct A
{
    
    
public:
	void PrintA()
	{
    
    
		cout << _a << endl;
		//这里_a相当于this->_a发生了对空指针解引用的情况
	}


	int _a;
};

int main()
{
    
    
	
    A* p = NULL;
	p->PrintA();
	//说明这里p->PrintA()等于(*p).PrintA()
	//但这里并没有语法错误:因为这里是调用里面函数,函数并不占用类的空间,因此可以调用类的函数
	//但是这里将p传进去了,p是一个空指针,在里面访问变量时,会产生对空指针解引用的情况,因此
	//具体的报错位置在函数里面的变量使用
}
  • Does the code report an error? Where is the specific error reported?
  • Report an error, and the error location is inside the function.
  • Essentially, calling this function is equivalent to passing parameters to the function, and using member variables is dereferencing!
struct A
{
    
    
public:

	void Show()
	{
    
    
		cout << "Show()" << endl;
	}

	int _a;
};

int main()
{
    
    
	
    A* p = NULL;

	p->Show();
}
  • Does the code report an error? Where is the specific error reported?

  • No error will be reported because there is no access to variables in the function.

  • Summary: The this pointer can be empty, but the function must be called through the object.

Guess you like

Origin blog.csdn.net/Shun_Hua/article/details/130339269