1. C++ 中定义一个类有哪两种方法?这两种方法有什么区别?
- C++ 中可以用
struct
、class
这两个关键字来定义类
- 区别:①
struct
成员和方法默认权限是 public ② class
成员和方法默认权限是private
2. C++ 编程规范(了解)
- 每个人都可以有自己的编程规范,没有统一的标准,没有标准答案,没有最好的编程规范。
- 全局变量:g_
- 成员变量:m_
- 静态变量:s_
- 常量:c_
3. 一个实例对象可以通过 对象
或 指针
访问属性,这两种方法有什么不同?
- 写法:对象用
.点语法
;指针用 ->箭头语法
- 汇编:对象是拿
首地址 + 偏移量
直接访问;指针是先 拿出指针所存首地址放到寄存器
然后再用 首地址 + 偏移量
访问;
- 补充:从汇编指令数目来讲,对象访问只需要一条指令,指针访问需要两条指令;所以用对象访问效率会高一些,但是我们通常用指针访问并不是为了提高效率。
// person.age = 10 对应的汇编代码
0x100003f9d <+13>: movl $0xa, -0x8(%rbp)
// p->age = 15 对应的汇编代码
0x100003fac <+28>: movq -0x10(%rbp), %rcx
0x100003fb0 <+32>: movl $0xf, (%rcx)
4. 下面代码,为什么实例对象只占 4 个字节(方法不占空间吗)?
struct People {
int age;
void display() {
age = 1;
}
};
- 方法存在代码块,不在实例对象中,实例对象只需存 age 即可,所以只需要 4 个字节。
5. 类实例调用方法,实例的在堆区或者栈区
,而方法存储在代码段
。那么方法里面的成员变量是怎么知道是哪个对象在调用该方法?
- 在调用方法的时候,编译器会将调用者做为
参数
,传递给方法。
0x100003d05 <+53>: movq -0x18(%rbp), %rdi
0x100003d09 <+57>: callq 0x100003d20
6. 思考下面代码的输出(领悟指针访问对象的真谛)?
struct Student {
int age
int height
int weight
void display() {
cout << age << endl
cout << height << endl
cout << weight << endl
}
}
int main() {
Student student
student.age = 10
student.height = 20
student.weight = 30
Student *s = (Student *)&(student.height)
s->age = 40
s->height = 50
// 第一次打印
student.display()
// 第二次打印
s->display()
return 0
}
- 第一次打印: 10 40 50
- 第二次打印: 40 50 未知
7. 怎么理解函数代码存储在代码段,函数调用的时候却在栈空间分配内存?
- 代码段:只存储了函数对应的汇编指令,而且代码段是只读的
- 栈空间:在函数调用时,才会真正给局部变量分配内存空间
8. 每个应用之间的内存是独立的吗?四个主要的内存区域依次是哪四个?
- 每个应用程序的内存空间都是独立的,互不干扰,都是虚拟内存
- 全局区 → 代码段 → 堆空间 → 栈空间
9. 思考栈空间也能分配空间给对象,那为什么还要堆空间呢?
- 栈空间的特定:在函数开始时内存由系统自动分配,在函数结束时内存由系统自动回收;
- 很多情况下我们需要自由控制
内存的分配的大小
,以及内存的生命周期
;
10. 在 C++ 中向堆空间申请\释放内存,有哪三种方式?
- malloc \ free
- new \ delete
- new[] \ delete[]
- 申请堆空间成功后,会返回那一段内存空间的地址
- 申请和释放必须是 1 对 1 的关系,不然可能会存在内存泄漏
11. 现在很多高级编程语言不需要开发人员去管理内存(比如 Java、OC、Swift),屏蔽了很多内存细节,这样有什么利弊?
- 利:提高开发效率,避免内存使用不当或泄漏
- 弊:不利于开发人员了解本质,永远停留在 API 调用和表层语法糖,对性能优化无从下手
12. 如果需要将较大的数据结构(比如对象、数组等)内存清零比较快的方法是什么?memeset(p, 1, 4)
是什么意思?
- 使用 memset 函数
memeset(p, 1, 4)
是将 4 个字节中的每个字节都设置为 1(注意不是将 4 个字节设置为 1
)
int main() {
Student s
s.age = 10
s.height = 10
s.weight = 10
s.display()
memset(&s, 0, sizeof(s))
s.display()
return 0
}