C++ articles--class size calculation, this pointer


1. Class size calculation

The size of a class is only calculated for its member variables or custom members, not for its member functions.

#include<iostream>
using namespace std;

class A1
{
    
    
public:
	void fun()
	{
    
    
		_a = 1;
		_b = 2;
	}

	int _a;
	int _b;
};

int main()
{
    
    
	cout << sizeof(A1) << endl;//8字节,为何是8字节
	
	return 0;
}

insert image description here

The byte size occupied by the member variables _a and _b in the class alone is 8, but there are also member functions in the class, why is it still 8 bytes? Is the member function not in the class? The correct class member function is in the
public In the code area, the member data of different objects is private. Everyone has their own member data
but the member functions are shared. At this time, others can also use them. All of them do not have to have member functions. Member functions take up more space.
After the class
but these houses do not necessarily have a basketball court (equivalent to a member function). If every house has a basketball court, it is conceivable I don’t know how big the house will be.
Secondly, many people come to the basketball court to play basketball. It’s impossible for you to play alone every time. It’s always boring. You have to ask your friends and neighbors to play together. If these friends and neighbors can also play, it’s better to repair it
. In the center of the community, this greatly saves space and its member functions are placed in the public code area, so it does not occupy the size of the class space

Class size when empty class or only member functions?

1 byte in size, it occupies one place, although a house may have nothing, but isn’t it a house, at least that piece of land is still a house, and it should have a place

#include<iostream>
using namespace std;

class A1//类中只有成员函数
{
    
    
	void fun()
	{
    
    }
};

class A2 {
    
    };//空类

int main()
{
    
    
	cout << sizeof(A1) << endl;
	cout << sizeof(A2) << endl;
	
	A1 a;
	A2 b;
	//虽然里面什么都没有但是这个位置是要在的
	cout << &a << endl;
	cout << &b << endl;
	return 0;
}

insert image description here

For class objects without member variables, 1 byte is required to occupy space, indicating that the object exists

Two, this pointer

As an invisible pointer to a member function, receiving the object address

#include<iostream>
using namespace std;

class day
{
    
    
public:
	void init(int year, int month, int day)
	{
    
    
		_year = year;
		_month = month;
		_day = day;
	}

	void Print()
	{
    
    
		//cout << this->_year  << '-' << this->_month << '-' << this->_day << endl;
		cout << _year << '-' <<_month << '-' << _day << endl;
	}
	int _year;
	int _month;
	int _day;
};

int main()
{
    
    
	day d1;
	day d2;
	d1.init(2023, 4, 24);
	d2.init(2022, 4, 24);

	d1.Print();
	d2.Print();

	return 0;
}

insert image description here

Although the two objects are initialized differently, when I call the print function, the actual parameters are not passed, and they are all called to the same address. Why are the results different?
Since the member function in the class is placed in the public code area, not in the object, the address of this function is fixed, so why are the results different
when two objects call it (function) (both call the same address)

It is because the compiler implicitly passes the address of the object as an actual parameter when the object is called, while the formal parameter of the function implicitly uses the this pointer to receive it. When calling, the address of the object is passed as the actual parameter by default.

Debug the program, then right-click the mouse, click to disassemble, and view the assembly code.
insert image description here
These assembly codes are pushing the actual parameters on the stack.
insert image description here

It can be found that when the member function Init was originally called, only three actual parameters were explicitly passed, but four parameters were pressed in the underlying assembly instruction, because the address of the object was implicitly pushed on the stack as the actual parameter.

insert image description here

When pushing the stack, the address of the object will be passed as an actual parameter to the member function it calls.

Under VS, the passing of this pointer is optimized, the address of the object is placed in the register (rcx), and the register (rcx) stores the value of this pointer

insert image description here

Print here has an implicit object parameter pointer, but it cannot be explicitly written out. The
object pointed to by this pointer cannot be modified, because this is modified by const (equivalent to day*const this) the object it points to cannot be modified
but it points to the object The content can be modified
, and the member variable of the object can be accessed through the this pointer.
Although the this pointer of the member function formal parameter cannot be written out explicitly,
it can be explicitly written out when the member variable in the object is to be accessed in the member function.

insert image description here
Can I access the member variables of the class in this way?

It cannot be directly accessed in this way. Even if it is a class, the members are all open to the outside world, but the member variables in the class are only declared, and they are not instantiated. Find the corresponding room, sorry impossible

insert image description here
So can you directly call the member function of the class in this way?

This kind of direct calling of its member functions in the class is actually not possible, because there is no object defined. When the compiler calls the Print function, it will implicitly pass the object address as an actual parameter. Here, even the object No how to call?

那么有人又会说,那我传空地址可否?在调用时,对象地址是隐晦的压栈,并不能显式的写出来,也是不行的

#include<iostream>
using namespace std;


class day
{
    
    
public:
	void init(int year, int month, int day)
	{
    
    
		_year = year;
		_month = month;
		_day = day;
	}

	void Print()
	{
    
    
		cout << this->_year  << '-' << this->_month << '-' << this->_day << endl;
	}
	int _year;
	int _month;
	int _day;
};

int main()
{
    
    
	day* p = nullptr;
	p->init(2023, 4, 24);
	p->Print();
}

insert image description here

Will p->initp calling the function init dereference this function? No, because the address of this function is not in this object, it will be passed as an actual parameter to this pointer in the public code area p
Although the definition class object is a null pointer, calling the class member initialization function does not report an error because No access to member variables in the object

insert image description here

This will cause an error, because the member in the object is accessed, but the value of the this pointer is empty, dereferencing the null pointer, such an extremely dangerous operation

Guess you like

Origin blog.csdn.net/m0_67768006/article/details/130381010