C++的编程规范
- 变量名的规范参考:
- 全局变量:g_xxx;
- 成员变量:m_xxx;
- 静态变量:s_xxx;
- 常量:c_xxx;
类
- 在C++中可以使用
struct
,class
来定义一个类; -
struct
与class
之间的区别:-
struct
的成员的默认权限是public
-
class
的成员的默认权限是private
-
#include <iostream>
using namespace::std;
struct Person {
//成员变量
int age;
//成员函数
void run() {
cout << "run() age = " << age <<endl;
}
};
class Student {
public:
int no;
void study() {
cout << "study() no = " << no <<endl;
}
};
int main(int argc, const char * argv[]) {
//已经创建了一个对象 已经分配了内存空间
//person对象在栈区分配内存
Person person1;
person1.age = 30;
person1.run();
Person person2;
person2.age = 33;
person2.run();
Student stu;
stu.no = 10;
stu.study();
return 0;
}
指针访问对象成员的本质
#include <iostream>
using namespace::std;
struct Person {
//成员变量
int m_age;
int m_width;
int m_height;
//成员函数
void run() {
cout << "run() age = " << m_age <<endl;
}
};
int main(int argc, const char * argv[]) {
//person对象在栈区分配内存
Person person;
person.m_age = 1;
person.m_width = 2;
person.m_height = 3;
person.run();
//定义一个指针变量 指向person对象
Person *ptr = &person;
ptr->m_age = 4;
ptr->m_width = 5;
ptr->m_height = 6;
ptr->run();
cout << sizeof(person) << endl;
cout << "&person = " << &person << endl;
cout << "&person.m_age = " << &person.m_age << endl;
cout << "&person.m_width = " << &person.m_width << endl;
cout << "&person.m_height = " << &person.m_height << endl;
return 0;
}
- 控制台调试结果如下:
- 打印结果显示
person
实例对象占用12个字节,其内存地址为0x7ffeefbff420
,在栈区分配内存,也是第一个成员m.age
的内存地址; - 汇编分析代码如下所示:
C++07_类`main:
0x100002ff0 <+0>: pushq %rbp
0x100002ff1 <+1>: movq %rsp, %rbp
0x100002ff4 <+4>: subq $0x50, %rsp
0x100002ff8 <+8>: movl $0x0, -0x4(%rbp)
0x100002fff <+15>: movl %edi, -0x8(%rbp)
0x100003002 <+18>: movq %rsi, -0x10(%rbp)
0x100003006 <+22>: movl $0x1, -0x20(%rbp)
0x10000300d <+29>: movl $0x2, -0x1c(%rbp)
0x100003014 <+36>: movl $0x3, -0x18(%rbp)
0x10000301b <+43>: leaq -0x20(%rbp), %rdi
0x10000301f <+47>: callq 0x100003170 ; Person::run at main.cpp:19
0x100003024 <+52>: leaq -0x20(%rbp), %rax
0x100003028 <+56>: movq %rax, -0x28(%rbp)
0x10000302c <+60>: movq -0x28(%rbp), %rax
0x100003030 <+64>: movl $0x4, (%rax)
0x100003036 <+70>: movq -0x28(%rbp), %rax
0x10000303a <+74>: movl $0x5, 0x4(%rax)
-> 0x100003041 <+81>: movq -0x28(%rbp), %rax
0x100003045 <+85>: movl $0x6, 0x8(%rax)
0x10000304c <+92>: movq -0x28(%rbp), %rdi
-
movl $0x1, -0x20(%rbp)
,立即数1,可知是将1写入(rbp-0x20)内存地址,所以(rbp-0x20)是m_age
的内存地址,也是实例对象person
的内存地址; -
leaq -0x20(%rbp), %rax
:将person
的内存地址写入rax; -
movq %rax, -0x28(%rbp)
:将rax中的内容即person
的内存地址写入(rbp-0x28)内存地址中,所以(rbp-0x28)就是指针变量ptr
的内存地址; -
movq -0x28(%rbp), %rax
:将指针变量ptr
的值即person
的内存地址写入rax中; -
movl $0x4, (%rax)
:将立即数4,写入person
的内存地址中,即person.m_age = 4
-
movl $0x5, 0x4(%rax)
:person
的内存地址+0x4,也就是m_width
的内存地址,即person.m_width = 5
-
movl $0x6, 0x8(%rax)
:person
的内存地址+0x8,也就是m_height
的内存地址,即person.m_height = 6
-
指针访问对象成员的本质:通过对象的内存地址+地址偏移进行访问;
this指针
-
this
是指向当前对象的指针; - 对象在调用成员函数的时候,会自动传入当前对象的内存地址;
#include <iostream>
using namespace::std;
struct Person {
//成员变量
int m_age;
int m_width;
int m_height;
//成员函数
void run() {
cout << "run() m_age = " << m_age <<endl;
cout << "run() m_width = " << m_width <<endl;
cout << "run() m_height = " << m_height <<endl;
cout << "run() m_age = " << this->m_age <<endl;
cout << "run() m_width = " << this->m_width <<endl;
cout << "run() m_height = " << this->m_height <<endl;
}
};
int main(int argc, const char * argv[]) {
//person对象在栈区分配内存
Person person;
person.m_age = 1;
person.m_width = 2;
person.m_height = 3;
person.run();
return 0;
}
- person实例对象在栈区分配内存;
- C++中类的成员函数方法在程序编译的时候,就全部存储在代码区,所以栈区对象调用代码区的函数方法时,会将栈区对象传递给函数方法;
- 汇编代码如下:
C++07_类`main:
0x100003050 <+0>: pushq %rbp
0x100003051 <+1>: movq %rsp, %rbp
0x100003054 <+4>: subq $0x20, %rsp
0x100003058 <+8>: movl $0x0, -0x4(%rbp)
0x10000305f <+15>: movl %edi, -0x8(%rbp)
0x100003062 <+18>: movq %rsi, -0x10(%rbp)
0x100003066 <+22>: movl $0x1, -0x20(%rbp)
0x10000306d <+29>: movl $0x2, -0x1c(%rbp)
0x100003074 <+36>: movl $0x3, -0x18(%rbp)
0x10000307b <+43>: leaq -0x20(%rbp), %rdi
-> 0x10000307f <+47>: callq 0x100003090 ; Person::run at main.cpp:28
0x100003084 <+52>: xorl %eax, %eax
0x100003086 <+54>: addq $0x20, %rsp
0x10000308a <+58>: popq %rbp
0x10000308b <+59>: retq
-
callq 0x100003090
:调用run方法,在此之前会执行leaq -0x20(%rbp), %rdi
即将实例对象person的内存地址写入rdi寄存器,为的就是在run方法中访问rdi寄存器,获取person的内存地址;
网友评论