总而言之就是: C++为了节省内存丧心病狂
1.假设A是struct 或 class ; 若A为空; sizeof(A)= 1; 若A不为空; sizeof(A)以内存对其方式计算.
2.区分:
(1)BBS(Block Start by Symbol):用来存放程序中未初始化的全局变量和静态变量(static)的一块内存区域.程序结束后系统自动释放(未初始化的全局变量在程序执行之前已清零;static默认初始值也为0)
(2)数据段(Data Segment):用来存放程序中已经初始化的全局变量的一块内存区域.(属于内存分配)
(3)代码段(Code Segment/Text Segment):用来存放程序执行代码的一块区域.(其大小在程序执行前就已经确定,并且一般是只读的)
(4)堆(Heap):用于存放进程中被动态分配的内存段,由程序员分配释放.(大小不固定,可动态增减)
(5)栈(Stack):用于存放程序临时创建的局部变量,也就是 块中/函数弧中定义的变量(不包括static).有编译器自动分配释放.
除此之外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且调用结束后,函数的返回值也会被存放回栈中.
3.访问vector中的数据有两种方法:
(1) vector::at() //首选,进行边界检查
(2) vector::operator[] //主要是为了与c兼容,可以像c数组一样操作,不做边界检查
4.(1)const 修饰类的成员函数,一般放在函数体后;
const void print(const int num) const {} //
// 第一个const修饰返回类型;第二个const修饰参数;第三个const修饰调用对象,也就是函数.
(2)const对象默认情况下只在当前文件下有效;若想多个文件共享,则需声明或定义为 extern const int x = 10;//这是个例子
5.(1)顶层const :指针本身是一个常量 : int const p1 //p1的值不能改变 //在const前说明是顶层
(2)底层const :指针所指的对象是常量 : const int *p2 //*p2不能改变
关于这两个的区别在函数参数传递,返回类型等还有很复杂的关系;最好亲自拜读c++ prime
6.指针和引用 ,,,,,,简直可怕
(1) 指针中存着这地址; 可以写成
int a =10;
int p1 =&a; //p1是int类型的变量; p1中存放着a的地址;p是指向a的指针; p1 == &a == 0x3443443424(某个地址) *p == a ==10;
而不能写成 int *p2 = a;
如果学过操作系统或计算机原理会好理解点,其实真的应该这样看 int* (p1 = &a); //当然这是错的
(2)引用即别名;
特别注意区分 * 在不同位置是 "指针"还是 "取内容"
& 是"引用"还是"取地址"
7.(1)常量指针必须初始化;\
(2)引用必须初始化,且不能用一个字面值常量初始化一个非常量引用; *****
但参数不会改变时,尽量使用常量引用,你会经常看到 bool fun(const int &s){;} 形式
(3)类的静态成员变量必须赋初值……(应该为必须"定义",即分配内存.解释:由于静态成员变量在类中仅仅是声明,没有定义,要在类的外面定义,实际上给它分配内存)
8.OOP三大特性:继承,多态,封装
(1)继承:子类自动继承其父级类中的属性和方法,并可以添加新的属性和方法或者对部分属性和方法进行重写。继承增加了代码的可重用性.
(2)多态:多个子类中虽然都具有同一个方法,但是这些子类实例化的对象调用这些相同的方法后却可以获得完全不同的结果,多态性增强了软件的灵活性.
(3)封装 :就是将一个类的使用和实现分开,只保留部分接口和方法与外部联系.
9.回调函数: 定义:如果你把 函数* 的指针(地址)作为参数传递给另一个参数,当这个指针被用来调用 其所指向的函数(就是函数*)时,我们就称之为回调函数.
理解:模块A要调用模块B中的某个函数b()来完成一定的功能;但是函数b()自己无法实现全部功能,需要反过来调用A中的某个函数a()来完成;则a()就是回调函数.
10.组合:以原有类的 对象 作为新类的数据成员;
继承:不改变现有的类,并采用现有类的形式并在其中添加新代码.