C++ classes and objects (detailed review)

A class is the realization of an object. A class in an object is an abstract concept, and a class is an object defined at the beginning of a program. An object defined by a class can be a real object in real life, or an object abstracted from real life. .

 1.1 C++ classes

1.1.1 Overview of classes

Objects in object-oriented need to be declared by defining classes. Objects are a kind of imagery. In the process of writing code, the functions of objects are realized by defining a class.

C++ class is different from class, classification, and type in Chinese. It is a special concept, which can be an overview of a unified thing, or a different node of a certain hierarchical structure. For example, all computers can be packaged as computer classes, all animals can be written as animal classes, etc. There are many similarities in many things in reality, and these similar things can be written as a class to reduce our workload. .

A class is a new data type, which is somewhat similar to a structure. A structure is a collection of different data types, and a class has more behaviors that can manipulate data types on the basis of a structure, that is, a function.

1.1.2 Class declaration and definition

In the section 1.1.1, the concept of class is explained a little, and it can be seen that class is a type independently developed by users. If you want to use the type of class in the program, you must design your own class according to what you need and declare the class, or use a class designed by others. Let's get to the point, how to design a class.

The format of a class declaration is as follows:

class class name identifier

{

        public:

                declaration of data members;

                declaration of member functions;

        private:

                declaration of data members;

                declaration of member functions;

        protected:

                declaration of data members;

                declaration of member functions;

};

The description of the class declaration format is as follows:

  class is a keyword that defines a class structure, and inside curly braces is called a class body or a class space.

  The class name identifier specifies the class name, and the class name is a new data type through which we can declare objects.

  Class members have two types: function and data.

  Inside the curly braces is the place to define and declare class members, and the keywords public, private, and protected are modifiers for class member access. 

The type of data members in the class can be arbitrary, including integer, floating point, character, array, pointer and reference (&), etc., and can also be an object. Objects of another class can be used as members of this class, but objects of its own class cannot be used as members of its own class, and pointers and medical objects of its own class can be used as members of its own class.

Note: There must be a semicolon after the curly braces when defining the class structure and defining the structure.

As follows, we declare a team information class:

class Cbasket
{
    /*数据成员*/
    int num;
    char name[128];
    char clothes[28];
    /*成员函数*/
    int setnum(int m_num);
    int getnum();
    int setname(char m_name[128]);
    char* getname();
    int setclothes(char m_clothes[28]);
    char* getclothes();
};

In the code, the class keyword is used to define the structure of the class. Cbasket is the class name of the defined team information. Three data members are included in the braces to represent the player's number, name, and clothing size (Cbasket Attributes), contains 6 member functions to represent the behavior of the Cbasket class.

 1.1.3 Class implementation

Section 1.1.2 just declares the members of the class in the Cbasket class. However, to use the methods in this class, that is, member functions, it is necessary to define its specific operations. Let's take a look at how to define the methods in the class.

The first method: define the member functions of the class in the class body. The following codes are stored in the basket.h header file, and the member functions of the class are defined in the class body.

#include<iostream>
#include<string.h>
using namespace std;

class Cbasket
{
public:
    //数据成员
    int m_num;
    char m_name[128];
    char m_clothes[28];
    //成员函数
    int setnum(int num)
    {
        m_num=num;
        return 0;     //执行成功返回0
    }
    int getnum()
    {
        return m_num;
    }
    int setname(char name[128])
    {
        strcpy(m_name,name);
        return 0;    //执行成功返回0
    }
    char* getname()
    {
        return m_name;
    }
    int setclothes(char clothes[28])
    {
        strcpy(m_clothes,clothes);
        return 0;    //执行成功返回0
    }
    char* getclothes()
    {
        return m_clothes;
    }
};

The second method: place the implementation of the member functions in the class body outside the class body, but if the class members are defined outside the class body, you need to use the domain operator "::", and place them in the class body and between the class body The external effect is the same, but the specific placement position is different. For specific differences, you can observe the difference between the code below and the code in the previous block.

#include<iostream>
#include<string.h>
using namespace std;

class Cbasket
{
public:
    //数据成员
    int m_num;
    char m_name[128];
    char m_clothes[28];
    //成员函数
    int setnum(int num);
    int getnum();
    int setname(char name[128]);
    char* getname();
    int setclothes(char clothes[28]);
    char* getclothes();
};
//类成员函数的实现部分
    int basket::setnum(int num)
    {
        m_num=num;
        return 0;     //执行成功返回0
    }
    int basket::getnum()
    {
        return m_num;
    }
    int basket::setname(char name[128])
    {
        strcpy(m_name,name);
        return 0;    //执行成功返回0
    }
    char* basket::getname()
    {
        return m_name;
    }
    int basket::setclothes(char clothes[28])
    {
        strcpy(m_clothes,clothes);
        return 0;    //执行成功返回0
    }
    char* basket::getclothes()
    {
        return m_clothes;
    }

Note that if you want to implement the member function outside the class body, you need to declare the function in the class body, otherwise it will not be available, and you need to use the :: symbol when implementing the member function externally.

There are two notes about the implementation of the class:

(1) The data members of the class need to be initialized, and the implementation code must be added to the member functions. Data members of a class cannot be initialized within the class declaration. It is an error to initialize as follows:

class Cperson

{

        int num=10; //Incorrect writing can not be initialized in the class

        char name[128]="Xiaoyuan"; //Incorrect writing can not be initialized in the class

        .....................................

        .....................................

};       

(2) The empty class is the simplest class in C++, and its declaration method is as follows:

class Cperson{  }; 

The empty class is only used as a placeholder, and class members and implementations are defined when necessary.

 1.1.4 Object declaration

After defining a new class, you can declare an object through the class name. The form of the declaration is as follows:

class name object name list

The class name is the identifier of the defined new class, and the object name table is the name of one or more objects. If multiple objects are declared, they must be separated by commas.

For example, declare an object as follows:

Cperson p; 

      Declare multiple objects as follows:

Cperson p1,p2,p3;

        After declaring the object, it is necessary to explain the reference of the object. There are two ways to refer to the object, one is the member reference method, and the other is the object pointer method.

(1) Member reference method

Member variable references are represented as follows:

objectname.membername 

Here "." is an operator whose function is to represent a member of an object,

The representation of member function application is as follows:

ObjectName.MemberName (parameter list) 

For example:

 Cperson p;

p.m_index;

(2) Object pointer method

The object name list in the object declaration form, in addition to multiple object names separated by a comma operator, can also be an object name array, object name pointer, and object names in the reference form.

The specific implementation is as follows:

Cperson *p;

Cperson p[10]; 

But if you want to use the members of the object, you need to use the "->" operator, which is the operator that represents the member, and has the same meaning as the "." operator. "->" is used to indicate the member pointed to by the object pointer, and the object pointer is a pointer to the object, for example:

Cperson *p;

p->m_index;

The following are two representations of object data members:

Object pointer name -> data member

(*object pointer name).data member

The same is true for the application of functions.

These two forms of representation are equivalent 

Using object reference members

In an instance, use the defined class to define an object, and then use that object to refer to its members

#include<iostream> 
#include<string.h>
using namespace std;
class stu{
	public:
		int m_num;
		char m_name[25];
		int m_year;
		//函数成员
		int getnum();
		int setnum(int num);
		int getyear();
		int setyear(int year);
		int setname(char name[25]);
		char* getname();
};


int stu::getnum()
{
	return m_num;
}
int stu::setnum(int num)
{
	m_num=num;
	return 0;
}
int stu::setyear(int year)
{
	m_year=year;
	return 0;
}
int stu::getyear()
{
	return m_year;
}
char* stu::getname()
{
	return m_name;
}
int stu::setname(char name[25])
{
	strcpy(m_name,name);
	return 0;
}

int main()
{
	stu y;
	int i=-1;
	int num,year;
	
	cin>>num;
	num=y.setnum(num);
	cout<<"m_num is"<<y.getnum()<<endl;
	
	cin>>year;
	year=y.setyear(year);
	cout<<"m_year is"<<y.getyear()<<endl;
	
	char name[]="小元";
	i=y.setname(name);
	cout<<"m_name is"<<y.getname()<<endl;
	return 0;
}

 The running code in this instance looks like this:

In the example, we can see that we define a y object for it, and then refer to the y object to refer to the member functions and data in the class, and refer to y to refer to m_num, m_name[25], m_year, getnum() in the class , setnum(int num), getyear(), int setname(char name[25]), char* getname() and other data types in classes.

 1.2 Constructor

1.2.1 Constructor overview

When an instance of a class enters the scope, that is, when an object is created, the constructor will be called by the program, then the function of the constructor is to initialize the object, such as assigning values ​​​​to data members and setting properties of the class etc., and these operations are just done in the constructor.

The constructor of a class can have parameters, which may or may not exist. The specific implementation is as follows:

class person
{
	public:
		int m_number;
		char m_name[128];
		person()	//无参构造函数对数据进行初始化 
		{
			m_number=10;
			cin>>m_name;
		}
		person(int num,char name)		//有参构造函数 
		{
			m_number=num;
			strcpy(m_name,name);	
		} 
};

 The code to use the constructor is as follows:

#include<iostream> 
#include<string.h>
using namespace std;

class person
{
	public:
		int m_number;
		char m_name[128];
		person()	//无参构造函数对数据进行初始化 
		{
			cout<<"请输入号码:"; 
			cin>>m_number;
			cout<<"请输入姓名:";
			cin>>m_name;
		}
		person(int num,char name[128])		//有参构造函数 
		{
			m_number=num;
			strcpy(m_name,name);	
		} 
		int getnum()
		{
			return m_number;
		}
		char* getname()
		{
			return m_name;
		}
};

int main()
{
	person p;
	cout<<"num is "<<p.getnum()<<endl;
	cout<<"name is "<<p.getname()<<endl;
	person t(30,"小侯");
	cout<<"num is "<<t.getnum()<<endl;
	cout<<"name is "<<t.getname()<<endl;
	return 0;
}

The result after the specific operation is:

Two objects p and t are declared in the program, p is initialized with the default constructor, and t is initialized with the constructor with parameters, so the results of calling the member functions of the same class are different.

 

1.2.2 Copy constructor 

It may be necessary to save a copy of the object in the development program in order to restore the state of the object in the process of subsequent execution. To restore the state of the object, the copy constructor can be used to generate an identical object for an already initialized object. When the copy constructor is called by the compiler to complete the construction and initialization of other objects based on the same class, its only Formal parameters must be references.

Application of copy constructor

#include<iostream>
#include<string.h>
using namespace std;

class phone
{
	public:
		char speak[128];
		phone(char spoken[128])
		{
			strcpy(speak,spoken);
		}
		phone(phone & copyp1)	//复制构造函数 
		{
			strcpy(speak,copyp1.speak);
		}
		char *speaker()
		{
			return speak;
		}
		int fix()
		{
			char name[28];
			cin>>name;
			strcpy(speak,name);
			cout<<"fixname is "<<speak<<endl;
			return 0;
		}
};

int main()
{
	phone p1("李牧歌");
	phone p2(p1);    //将对象p1的内容复制给p2
	cout <<"name is "<<p1.speaker()<<endl;
	cout<<"name is "<<p2.speaker()<<endl;
	p1.fix(); 
	return 0; 
}

To run the program, first declare p1 with the parameterized constructor, and then declare p2 through the copy constructor, because p1 is already an initialized class object, and can be used as a parameter of the copy constructor. It can be seen from the output that the two objects are the same .

The result of the operation is as follows:

 1.3 Destructors

Constructor and destructor are two special member functions in class body definition, neither of them return a value. The constructor name identifier is the same as the class name identifier, and the destructor name identifier is to add a "~" symbol before the class name identifier.

As long as the constructor is used immediately after the object is created to assign values ​​to some data members in the object, the main purpose is to initialize the object. The main function of the destructor is to release an object. Before the object is deleted, the destructor and the constructor are just the opposite.

 The use of destructors

#include<iostream>
#include<string.h>
using namespace std;

class stu
{
	public:
		int m_num;
		stu();
		~stu();	//析构函数	
		int get();	
		char* m_pass;
};

stu::stu()
{
	cout<<"请输入学生的学号:"<<endl;
	cin>>m_num;
	m_pass=new char[128];
}
stu::~stu()		
{
	delete[] m_pass;	//删除m_pass的内容 
	m_num=0;
}
int stu::get()
{
	cout<<"学号是:"<<m_num<<endl;
	strcpy(m_pass,"恭喜你通过了!");
	cout<<m_pass<<endl;
	return 0;
}

int main()
{
	stu s;
	s.get();
	return 0;
}

The program runs as shown in the figure:

The program uses new in the constructor to allocate space for the member m_pass, and uses delete in the destructor to release the space allocated by new. The member m_pass is a character pointer, and the content pointed to by the character pointer is output in the get function.

 Things to note when using destructors:

(1) Only one destructor can be defined in a class.

(2) The destructor cannot be overloaded.

(3) Constructors and destructors cannot use the return statement to return a value without adding the keyword void.

The calling environment of constructors and destructors

(1) The scope of the automatic variable is a certain module. When the module is activated, the automatic variable calls the constructor, and the destructor is called when the module is exited. 

(2) The global variable will call the constructor before entering the main() function, and the destructor will be called when the program terminates.

(3) The dynamically allocated object will call the constructor when using nre to allocate memory for the object; the destructor will be called when using delete to delete the object.

(4) Temporary variables are automatically generated by the compiler to support calculations. The constructor and destructor are called at the beginning and end of the lifetime of the temporary variable.

1.4 Class members

1.4.1 Accessing class members

The three major characteristics of classes include "encapsulation". The data encapsulated in the class can be set to be visible or invisible to the outside world. The keywords public, private, and protected can be used to set whether the data members in the class are visible or invisible to the outside world, that is, whether other classes can access the data members.

The keywords public, private, and protected indicate whether the class members are public, private, or protected. These 3 keywords divide the class into 3 areas. The class members in the public area can be accessed outside the scope of the class, while the private area and protected area can only be accessed in the scope of the class.

If the private area is to be accessed by external classes, you need to use friends, and the protected area can be accessed by derived classes. 

If no keywords are added to the class, the system default state class members are all in the private area.

The specific settings are as follows:

class basket
{
	private:
		int num;
	public:
		int getnum() {return num};
		int setnum(){num=15 retrun 0;};	
}; 

This setting is that num cannot be accessed externally, but the value of num can be accessed by the outside world and specific operations on num can be performed through shared functions.

With different areas, developers can encapsulate according to requirements, and define class members that do not want to be accessed and called by other classes in the private area and protected area, which ensures the concealment of class members.

The termination of each region is to wait until the next region appears.

 1.4.2 Inline member functions

When defining a function, you can use the inline keyword to define the function as an inline function. When defining a member function of a class, you can also use the inline keyword to define the member function as an inline member function. In fact, for member functions, if the definition is in the class body. Even without the inline keyword, the member function is still an inline member function. For example

class basket
{
	private:
		int num;
	private:
		inline int getnum()const;	//定义一个内联成员函数 
		int setnum();	
}; 
int basket::getnum()const
{
	return num;
}
int basket::setnum()
{
	cin>>num;
}

class basket
{
	private:
		int num;
	private:
	int getnum()const;	//定义一个成员函数 
		int setnum();	
}; 
inline int basket::getnum()const	//函数为内联成员函数 
{
	return num;
}
int basket::setnum()
{
	cin>>num;
}

The above codes respectively define an inline member function in the class body, and one defines an inline member function outside the class body.

The code in the program demonstrates where it should be called an inline function using the inline keyword. For inline functions, the program will directly insert the code of the function at the place where the function is called. If there are many statements in the function body, the program code will expand. If the destructor of the class is defined as an inline function, it may cause Leading to potential code bloat.

Concatenated functions need to pay attention to:

(1) Loops and switch statements are not allowed in inline member functions.

(2) The definition of an inline function must appear before its first call.

The difference between inline functions and different functions is that when a function is called, the program will jump into the function body for execution, and after the execution is completed, it will return to the statement that called it, while the inline function uses the expression of the call as an inline function Body to replace, similar to re-write the code at the calling statement.

1.4.3 Static class members

The class members defined before this section are all accessed through objects, not directly through the class name. If a class member is defined as a static class member, direct access using the class name is allowed. Static class members are identified using the static keyword before the class member definition. For example

class Cbook

{

public:

        static int m_price;

}; 

When defining static data members, it is usually necessary to initialize the static data members outside the class body. For example

int Cbook::m_price=10; 

For static data members, not only can be accessed through the object, but also can be accessed by directly using the class name. For example

int main()

{

        Cbook book; //Define a Cbook class object book 

        cout<<Cbook::m_price<<endl; //Access static members by class name 

        cout<<book.m_price<<endl; //Access static members through objects

        return 0;

}

In a class, static data members are shared by all class objects, and if a static member of one object changes, the rest of the static members will also change.

For static data members, you also need to pay attention to the following points.

Static data members can be of the type of the current class, while other data members can only be of the pointer or reference type of the current class.

class Cbook
{
	public:
		static int m_price;
		Cbook m_book 	//非法的定义,不允许在类中定义所属类的对象
		static Cbook m_Vcbook 	//正确静态数据成员允许定义所属类的对象
		Cbook *m_pbook;		//正确可以是指针或引用的类型	
}; 

Static data members can be used as default parameters of member functions (ordinary member functions cannot be used as default parameters and cannot be assigned at parameters)

class Cbook
{
	public:
		static int m_price;	//定义一个静态数据成员 
		int m_num;
		void output(int data=m_price)	//定义一个函数,将静态数据作为默认参数 
		{
			cout<<data<<endl;
		} 
		void ouputnum(int num=m_num)	//错误的定义,类的普通成员不能作为默认参数
		{	
			cout<<num<<endl;
		}	 
}; 

 A static member function of a class can only access the static data members of the class, not ordinary data members.

class Cbook
{
	public:
		static int m_price;	//定义一个静态数据成员 
		int m_num;
		static void output()	//定义一个静态成员函数
		{
			cout<<m_price<<endl;	//可以访问静态数据成员
			cout<<m_num<<endl;		//错误,静态函数只能访问静态成员 
		} 
}; 

In addition, static member functions cannot be defined as const functions, that is, the const keyword cannot be used at the end of static member functions. For example, the following static member function is illegal.

static void ouput()const;

When defining a static data member function, if the implementation code of the function is outside the class body, there is no need to add the static keyword in the implementation part, otherwise illegal behavior will occur. 

 This blog ends here first, as shown in the picture above: Life is like a journey against the road, and I am also a pedestrian. Don't feel anxious because what you do is different from what you do, because there are very few people who walk with you on the road of life. I hope everyone can continue to explore in their respective fields of study.

Guess you like

Origin blog.csdn.net/m0_61886762/article/details/124854684