C++知识点总结(面向对象1-类和对象, this指针, 内存布局)

面向对象1-类和对象

C++中可以使用struct, class来定义一个类
struct 和 class的区别:struct的默认成员权限是public
class的默认的成员权限是private
变量名规范参考:
全局变量: g_ global g_age
成员变量: m_ member m_age
静态变量: s_
常量: c_ const
或使用驼峰标识 gAge, mAge

面向对象2- 对象的内存

#include <iostream>
using namespace std;

class Person {
public:
    int m_id;
    int m_age;
    int m_height;
    void display() {
        cout << m_id << m_age << m_height << endl;
    }
};

int main()
{
    Person person;
    person.m_id = 1;
    person.m_age = 2;
    person.m_height = 3;
	cout << &person << endl;
	cout << &person.m_id << endl;
	cout << &person.m_age << endl;
	
    return 0;
}

在这里插入图片描述

面向对象3-this

函数都存储在代码段
局部变量存储在栈区
那怎么访问person1, person2对象的成员变量的?其实内部有this指针, 隐式参数,看不到,在调用函数会把调用者的地址传过去

面向对象4-指针访问的本质

原理:如何利用指针间接访问所指向的对象的成员变量?
1.从指针中取出对象的地址
2.利用对象的地址 + 成员变量的偏移量计算出成员变量的地址
3.根据成员变量的地址访问成员变量的存储空间

面向对象5-指针的思考题

面向对象6-0xCC

涉及到函数调用栈
每调用一个函数时, 会给这个函数分配一个栈空间, 但这个栈空间里面的数据可能是垃圾数据, 也可能是之前别的函数用过的, 所以在真正在用这个栈空间之前,会用CC来填充栈空间, 使这个栈空间里面的数据全是C,为什么用CC来抹掉之前的数据, 不用00呢?
什么是CC?
如果把CC当做机器码来看的话, 对应的汇编代码是int3, int3 : 起到断点的作用. int3是断点的意思
在汇编里面int叫做中断, 后面的3是中断码,中断码是3就是断点的意思
int - interrupt
好处: 假设jmp, jz 后面跟的地址值指错了, 指成了函数的栈空间,那么一跳转到函数的栈空间, 就会执行int3就会停下来, 就不至于假设以前是一些垃圾数据, 可能做一些危险的指令操作.变得安全.这样的话, 函数的栈空间不小心被别人当做代码来执行, 那也很安全了.
函数代码在代码段, 调用函数, 执行函数代码其实就是CPU在访问代码区的内存(机器指令).
为什么函数代码在代码区, 又要给函数分配一段栈空间呢?
因为在函数里面要定义局部变量, 所以在调用函数时, 要分配一段额外的空间来存放局部变量.
因为代码区是只读的, 而函数内部的局部变量是可以改的, 所以选择了栈空间.

内存-封装, 内存布局, 堆空间

封装

成员变量私有化, 提供公共的getter和setter给外界去访问成员变量.

内存空间的布局

每个应用都有自己独立的内存空间, 其内存空间一般都有以下几大区域:
1.代码段(代码区)(Code )
用于存放代码(机器指令)
2.数据段(全局区)
用于存放全局变量等
3.栈空间
(1)每调用一个函数就会给它分配一段连续的栈空间, 等函数调用完毕后会自动回收这段栈空间.
(2)自动分配和回收
4.堆空间
需要主动去申请和释放

堆空间

(1)堆空间的价值:
在程序运行过程, 为了能够自由控制内存的生命周期, 大小, 会经常使用堆空间的内存.
(2)堆空间的申请\释放
1.malloc\free
2.new \ delete
int *p = new int;
*p = 10;
delete p;
只要看到new就是向堆空间申请内存
申请什么看右边, new int 就是申请一个int类型大小的空间,不用强制类型转换.
所以直接new int 就是向堆空间申请4个字节, 并且把这4个字节地址值赋值给左边的指针
char *p = new char;
*p = 10;
delete p;
这个是申请1个字节
3.new [] \ delete[]
char *p = new char[4];
申请了4个连续的字节
delete[] p;

注意:
申请堆空间成功后, 会返回那一段内存空间的地址
申请和释放必须是1对1的关系, 不然可能会存在内存泄露.

内存-堆空间的初始化

(1)malloc是否初始化与编译器有关
memset 函数 memory set
int *p = (int * )malloc(sizeof(int)*10);
memset(p, 0, 40);
第一个参数是内存地址
第二个参数是初始化为什么值
第三个参数是初始化多少字节
意思是:从p这个地址开始连续的40个字节, 每一个字节都设置为0
(2)new \ delete
int *p0 = new int; 不会初始化
int *p1 = new int(); 默认初始化为0
int *p2 = new int(5); 初始化为传入的值
int *p3 = new int[3]; 数组元素未被初始化
int *p4 = new int3; 3个数组元素都被初始化为0
int *p5 = new int[3]{}; 3个数组元素都被初始化为0
int *p6 = new int[3]{5}; 数组首元素初始化为5, 其他元素都是0

内存-对象的内存

对象的内存可以存在于3种地方:
全局区(数据段): 全局变量
栈空间:函数里面的局部变量
堆空间:动态申请内存(malloc, new等)
在这里插入图片描述


其他C++系列文章:

C++知识点总结(基础语法1-函数重载, 默认参数)
C++知识点总结(基础语法2-内联函数, const, 引用)
C++知识点总结(面向对象1-类和对象, this指针, 内存布局)
C++知识点总结(面向对象2-构造函数, 初始化列表)

C++知识点总结(面向对象3-多态)

C++知识点总结(面向对象4-多继承, 静态成员static)
C++知识点总结(面向对象5-const成员, 拷贝构造函数)
C++知识点总结(面向对象6-隐式构造, 友元, 内部类, 局部类)
C++知识点总结(其他语法1-运算符重载)
C++知识点总结(其他语法2-模板, 类型转换, C++11新特性)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章