C++ object pointer

1. The general concept of object pointer

Like variables of basic types, each object occupies a certain amount of space in memory after initialization. Therefore, an object can be accessed either by the object name or by the object address. Although the object contains both data and function members, which is slightly different from general variables, the memory space occupied by the object is only used to store data members, and function members do not have copies in each object. An object pointer is a variable used to store the address of an object. Object pointers follow the same rules as general variable pointers.

(1) Declare the object pointer

The general syntax for declaring a pointer to an object is:

类名*对象指针名;

For example:

Point p1;//声明Point类的对象p1
Point *pointPtr;//声明Point类的对象指针变量PointPtr
PointPtr=&p1;//将对象p1的地址赋给PointPtr,使PointPtr指向p1

(2) Use the object pointer to access the members of the object

Just like accessing the members of the object through the object name, you can easily access the members of the object by using the object pointer. The syntax is:

对象指针名->成员名;

This form (*对象指针名).成员名is equivalent to the access form of " ".

[Example 1] Use pointers to access members of the Point class.

class Point//定义Point类
{
    
    
public://外部接口
	Point(int x=0,int y=0):x(x),y(y){
    
    }//构造函数
	int getX() {
    
     return x; }//返回x
	int getY() {
    
     return y; }//返回y
private://私有数据
	int x, y;
};

int main()
{
    
    
	Point a(4, 5);//定义并初始化对象a
	Point* p1 = &a;//定义对象指针p1,用a的地址将其初始化
	cout << p1->getX() << endl;//利用指针访问对象成员
	cout << (*p1).getX() << endl;//利用指针访问对象成员
	cout << a.getX() << endl;//利用对象名访问对象成员
	return 0;
}

Running results:
insert image description here
Analysis:

The object pointer must be initialized before use, so that it points to an object that has been declared, and then used. The public members of the object can be accessed through the object pointer.

[Example 2] Rewrite the following error code as correct

error code:

class A;
class B
{
    
    
	A x;
};
class A
{
    
    
	B y;
};

Cause of error:
Class B cannot use objects of class A when the definition of class A is not perfect.

Modified code;

class A;
class B
{
    
    
	A* x;
};
class A
{
    
    
	B y;
};
int main()
{
    
    
	return 0;
}

Here, it is allowed to declare a pointer of class A in class B, and the definition of class A is located after the complete definition of class B. Of course, objects of class B can be declared as data members.

2. this pointer

The this pointer is a special pointer implicit in the non-static member functions of each class (including constructors and destructors), which is used to point to the object currently being operated by the member function.

[Note] The this pointer is actually an implicit parameter of the class member function. When calling a member function of a class, the address of the object currently operated by the member function will be automatically passed to the called member function as the value of the parameter, so that the called function can access the current object being operated through the this pointer The data members of the object. For const member functions, this implicit parameter is of const pointer type.

Every time a member function is called, there is an object that is currently being operated by the member function, and the this pointer is a pointer to the object that is currently being operated.
For example:

class Point//定义Point类
{
    
    
public://外部接口
	Point(int x=0,int y=0):x(x),y(y){
    
    }//构造函数
	int getX() {
    
     return x; }//返回x
	int getY() {
    
     return y; }//返回y
private://私有数据
	int x, y;
};

int main()
{
    
    
	Point a(4, 5);//定义并初始化对象a
	Point* p1 = &a;//定义对象指针p1,用a的地址将其初始化
	cout << p1->getX() << endl;//利用指针访问对象成员
	cout << (*p1).getX() << endl;//利用指针访问对象成员
	cout << a.getX() << endl;//利用对象名访问对象成员
	return 0;
}

Member functions in the above code:

int getX()
{
    
    
	return x;
}

Among them return x;, the system needs to distinguish which object the assigned data member belongs to each time this statement is executed, and the this pointer is used. For the system, each call is equivalent to executing:

return this->x;

The this pointer clearly points out the object to which the data currently operated by the member function belongs. The actual process is that the this pointer is an implicit formal parameter of a member function. When a member function is called through an object, the system first passes the address of the object to the member function through a parameter, and the member function then calls the data member of the object. To operate, the this pointer is implicitly used.

The this pointer is a pointer constant. For constant member functions, this is also a pointer to a constant. In a member function, you can use *this to identify the object on which the function is being called.

[Note] When an identifier with the same name as a class member is declared in the local scope, the direct reference to the identifier represents the identifier declared in the local scope. At this time, in order to access the class member, you can pass this pointer.

3. A pointer to a non-static member of a class

The members of the class also have some variables, functions or objects, etc., so their addresses can also be directly stored in a pointer variable, so that the pointer can directly point to the members of the object, and then the members of the object can be accessed through these pointers.

A pointer to an object member must be declared before being used, then assigned, and then referenced. So first declare a pointer to a member of the object's class.

(1) The general form of the declaration pointer statement is:

类型说明符 类名::*指针名;//声明指向数据成员的指针
类型说明符 (类名::*指针名)(参数表)//声明指向函数成员的指针

After declaring a pointer to a member, it needs to be assigned, that is, to determine which member of the class it points to.

(2) The grammatical form of assigning a value to a data member pointer is generally:

指针名=&类名::数据成员名;

(3) Use member function pointers to access member functions

[Note] When taking the address of a class member, you must also abide by the agreement on access rights, that is, you cannot take the address of its private members outside the scope of a class.

For an ordinary variable, use the "&" operator to get its address, and assign the corresponding address to a pointer to access the variable through the pointer. But for members of classes, the problem is more complicated.

The definition of a class only determines the type of each data member, the memory size it occupies and their relative positions, and does not assign corresponding addresses to the data members when it is defined. Therefore, after the above assignment, it only shows which data member the assigned pointer is specially used to point to, and at the same time, the pointer stores the relative position of the data member in the class (that is, the address offset relative to the starting address), of course There is nothing currently accessible through such a pointer.

Because the class is instantiated through the object, memory space will be allocated for the specific object when the object of the class is declared. At this time, it is only necessary to combine the starting address of the object in memory with the relative offset stored in the member pointer. The data members of the object can be accessed. When accessing data members, this combination can be achieved with the following two syntax forms:

对象名.*类成员指针名;

or

对象指针名->*类成员指针名;

[Example] Different ways to access public members of an object

class Point//定义Point类
{
    
    
public://外部接口
	Point(int x = 0, int y = 0) :x(x), y(y) {
    
    }//构造函数
	int getX() {
    
     return x; }//返回x
	int getY() {
    
     return y; }//返回y
private://私有数据
	int x, y;
};

int main()
{
    
    
	Point a(4, 5);//定义并初始化对象a
	Point* p1 = &a;//定义对象指针p1,用a的地址将其初始化
	int(Point:: * fun)() = &Point::getX;//定义成员函数指针并初始化

	cout << (a.*fun)() << endl;//使用成员函数指针和对象名访问成员函数
	cout << (p1->*fun)() << endl;//使用成员函数指针和对象指针访问成员函数
	cout << a.getX() << endl;//使用对象名访问成员函数
	cout << p1->getX() << endl;//使用对象指针访问成员函数
	return 0;
}

operation result:
insert image description here

(4) Assignment to the member function pointer
After the member function pointer is declared, the statement of the following form should be used to assign a value to it:

指针名=&类名::函数成员名;

[Note] Constant member functions and ordinary member functions have different types, so pointers that can be assigned by constant member functions need to be explicitly written with the const keyword when declaring.

(5) Call member functions using member function pointers

The function name of an ordinary function represents its start address, and the start address can be assigned to the pointer, and the function can be called through the pointer. Although the member function of the class does not make a copy in each object, it must call the non-static member function through the object because it needs to determine the this pointer. Therefore, after the above-mentioned assignment to the member function pointer, the member function cannot be called directly by the pointer, but the object of the class needs to be declared first, and then the member function is called by the pointer using the following formal statement:

(对象名.*类成员函数指针名)(参数表)

or

(对象指针名->*类成员函数指针名)(参数表)

The return value type and function parameters in the declaration, assignment, and use of member function pointers must match each other.

3. A pointer to a static member of a class

The access to the static members of the class does not depend on the object, so the static members can be pointed to and accessed through ordinary pointers.

[Example 1] Access the static data members of the class through pointers.

class Point//定义Point类
{
    
    
public://外部接口
	static int count;//声明静态数据成员,用于记录点的个数
	Point(int x = 0, int y = 0) :x(x), y(y) //构造函数
	{
    
    
		count++;
	}
	Point(const Point& p) :x(p.x), y(p.y)
	{
    
    
		count++;
	}
	~Point()
	{
    
    
		count--;
	}
	int getX() {
    
     return x; }//返回x
	int getY() {
    
     return y; }//返回y

private://私有数据
	int x, y;
};

int Point::count = 0;//静态数据成员定义和初始化,使用类名限定

int main()
{
    
    
	int* p = &Point::count;//定义一个int型指针,指向类的静态成员
	Point a(4, 5);//定义并初始化对象a
	cout << "点A为:(" << a.getX() << "," << a.getY() << ")  ";
	cout << "对象的个数=" << *p << endl;//直接通过指针访问静态数据成员
	Point b(a);//定义对象b,并用a对象对其进行初始化
	cout << "点B为:(" << b.getX() << "," << b.getY() << ")  ";
	cout << "对象的个数=" << *p << endl;//直接通过指针访问静态数据成员
	
	return 0;
}

Running result:
insert image description here
[Example 2] Access the static function member of the class through the pointer.

class Point//定义Point类
{
    
    
public://外部接口
	Point(int x = 0, int y = 0) :x(x), y(y) //构造函数
	{
    
    
		count++;
	}
	Point(const Point& p) :x(p.x), y(p.y)
	{
    
    
		count++;
	}
	~Point()
	{
    
    
		count--;
	}
	int getX() {
    
     return x; }//返回x
	int getY() {
    
     return y; }//返回y

	static void ShowCount()//输出静态数据成员
	{
    
    
		cout << "  对象的个数=" << count << endl;
	}

private://私有数据
	int x, y;
	static int count;//静态数据成员声明,用于记录点的个数
};

int Point::count = 0;//静态数据成员定义和初始化,使用类名限定

int main()
{
    
    
	void(*fun)() = Point::ShowCount;//定义一个指向函数的指针,指向类的静态成员函数
	
	Point a(4, 5);//定义并初始化对象a
	cout << "点A为:(" << a.getX() << "," << a.getY() << ")  ";
	fun();//输出对象个数,直接通过指针访问静态函数成员
	Point b(a);//定义对象b,并用a对象对其进行初始化
	cout << "点B为:(" << b.getX() << "," << b.getY() << ")  ";
	fun();//输出对象个数,直接通过指针访问静态函数成员

	return 0;
}

operation result:
insert image description here

Guess you like

Origin blog.csdn.net/NuYoaH502329/article/details/132107958