1直接对象访问成员
#include<iostream>
using namespace std;
int main() {
struct Person
{
int m_id;
int m_age;
int m_height;
void display() {
cout << "m_id=" << m_id << endl;
cout << "m_age=" << m_age << endl;
cout << "m_height=" << m_height << endl;
};
};
Person person;
person.m_id = 10;
person.m_age = 20;
person.m_height = 30;
person.display();
//Person* p = &person;
//p->m_id = 10;
//p->m_age = 20;
//p->m_height = 30;
//p->display();
//Person* p1 = (Person*)&person.m_age;
////p1->m_id = 10;
//p1->m_id = 40;
//p1->m_age = 50;
//p1->display();
////person.display();
return 0;
}
对应汇编
解释:
显然直接每次赋值直接一步到位,0Ah即10,赋值给[ebp-14h]这个地址,[eb0-14h]==m_id的地址==Person的地址
后面的_age和_height即在0Ah+4=14h 0Ah+4+4=1Eh
[ebp-10h]==_age地址
[ebp-0Ch]==_heigh地址.
2通过指针访问成员
#include<iostream>
using namespace std;
int main() {
struct Person
{
int m_id;
int m_age;
int m_height;
void display() {
cout << "m_id=" << m_id << endl;
cout << "m_age=" << m_age << endl;
cout << "m_height=" << m_height << endl;
};
};
Person person;
//person.m_id = 10;
//person.m_age = 20;
//person.m_height = 30;
//person.display();
Person* p = &person;
p->m_id = 10;
p->m_age = 20;
p->m_height = 30;
p->display();
//Person* p1 = (Person*)&person.m_age;
////p1->m_id = 10;
//p1->m_id = 40;
//p1->m_age = 50;
//p1->display();
////person.display();
return 0;
}
对应汇编
lea rax,[rbp+8]
mov qword ptr [rbp+38h],rax
mov rax,qword ptr [rbp+38h]
mov dword ptr [rax],0Ah
mov rax,qword ptr [rbp+38h]
mov dword ptr [rax+4],14h
mov rax,qword ptr [rbp+38h]
mov dword ptr [rax+8],1Eh
mov rcx,qword ptr [rbp+38h]
分析
显然每次赋值用了2句。
[rbp+8] 表示指针地址
[rbp+38h] 表示person地址==m_id地址
[rax+4]==m_id+4==_age地址
[rax+8]==m_height地址
例如1先将[rbp+8] 的地址给了rax 2 把rax里面存放的地址mov入 [rbp+38h]
也就是说指针地址为[rax]指向person地址==m_id地址
而[rax+4]的意思就是_age地址
//原理:如何利用指针间接访问所指向对象的成员变量?
1.从指针中取出对象的地址
2.利用对象的地址+成员变量的偏移量计算出成员变量的地址
3.根据成员变量的地址访问成员变量的存储空间