C++笔记:
一、const修饰变量
? 1. const修饰 普通变量;
const int a=10;
? 2. const修饰 指针常量, 这时的指针指向的地址空间不能变,但是该地址空间存放的内容却可以变;
int *const p;
? 3. const修饰 常量指针,这时指针可以时任何内存空间,但是内存空间里的值一定不能变;
const int* p;
二、static静态变量关键字
??static 静态变量声明有以下四种方式:局部静态变量、全局静态变量、类静态成员变量 以及类中的静态成员方法; ? ?局部静态变量 :局部静态变量 存储在 静态存储区上,程序运行期间只被允许初始化一次,作用域仍然为局部作用域,在变量定义的函数或语句块中有效,程序结束时由操作系统回收资源,静态局部变量不会因为函数体的调用结束而释放。 ? ?全局静态变量 : 存储在静态存储区,静态存储区中的资源在程序运行期间会一直存在,直到程序结束由系统回收。未初始化的变量会默认为0,作用域在声明他的文件中有效。 ? ?类静态成员变量 : 被类的所有对象共享,包括子对象。必须在类外初始化,不可以在构造函数内进行初始化。 ? ?类静态成员函数 : 所有对象共享该函数,不含this指针,不可使用类中非静态成员。
三、全局变量与静态全局变量的异同点:
? ? 相同点: ? ? ? 全局变量和静态全局变量都存储在静态存储区,但是全局变量不是静态变量。 ? ? 不同点: ? ? ?全局变量:在主函数外部(就是#include<库> 后面),可以跨文件调用, 如果要在其他文件使用该全局变量,则需要在该文件中一开始处添加extern来修饰全局变量。 ? ? ?静态全局变量:就是在全局变量的前面加了个static修饰,他不允许跨文件调用,只允许在本文件中使用。
四、指针空值类型-nullptr
?? 首先,先介绍NULL, NULL 在C语言中被看成是空指针,在C++中被定义成0.
int* ptr1=NULL;
char* ptr2=NULL;
void* ptr3=ptr2
void* ptr3= (void*) ptr2;
??现在,我们来介绍nullptr, nullptr为空指针,可以自动的转化成其他指针类型:
int* ptr1=nullptr;
char* ptr2=nullptr;
void* ptr3=ptr2
??在C++11标准下, 相比NULL和0,使用nullptr初始化空指针可以使我们编写的程序更加健壮。
五、指针和引用的异同
??指针:是一个变量,但是这个变量存储的是另一个变量的地址,我们可以通过访问这个地址来修改变量。
??引用:是一个别名,还是变量本身。对引用进行的任何操作就是对变量本身进行的操作。
??相同点:二者都可以对变量进行修改。 ??不同点:指针可以有多级,但是引用只有一级(int&& a不合法, int** p合法);sizeof指针可以得到指针本身大小,sizeof引用得到的是变量本身大小; 指针传参还是值传递,引用传参传的是变量本身。
六、类的继承与多态
-
类的三要素:封装,继承,多态; -
公有成员,保护成员 和 私有成员的区别:公有成员可以暴露在类外,由类对象直接访问;私有成员只能有类内或者友元函数才能访问;保护成员只能有该类内,派生类的类内或者友元函数中才能访问。 -
继承的三种方式:公有继承、保护继承和私有继承。 -
多态必须满足的3个条件: 1 .子类继承父类;2. 子类重写父类的虚函数; 3. 父类引用指向子类对象 (即父类中的同名函数必须定义为虚函数)。 override作用是:在继承多态时候,检查子类是否重写父类虚函数,如果没有重写,就会出现语法错误。override关键字 同样是写在函数名后面 -
类访问修饰符:public, private, protected ; -
类的特殊函数: (1) 构造函数:类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。构造函数可以有多个; (2) 析构函数:类的析构函数是类的一种特殊成员函数,它会在每次删除所对象时执行,且只能有一个。 (3) 拷贝构造函数: 利用一个已经存在的对象来创建另一个在的对象。 (4) 友元函数:类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数。
class Box{
public:
double width;
friend void printWidth( Box box );
void setWidth( double wid );
};
void printWidth( Box box )
{
cout << "Width of box : " << box.width <<endl;
}
- 纯虚函数:virtual 修饰,且只定义并没有实现; 如果类中的含有纯虚函数,那么这个类就为抽象类,抽象类不能实例化对象。
- 虚函数:virtual修饰,定义且具体实现,子类重写父类虚函数,在调用时会告诉编译器不要静态链接到父类的该函数。我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接。
六、函数重载、重写、隐藏
??重载:在同一作用域中,两个函数名相同,但是参数列表不同(个数、类型、顺序),返回值类型必须一样; ??重写:子类继承了父类,父类中的函数是虚函数,在子类中重新定义了这个虚函数,这种情况是重写; ??隐藏: 子类中函数与基类中的函数同名,但这个函数在基类中并没有被定义为虚函数,此时基类的函数会被隐藏;
??构造函数可以重载,即可以有多个构造函数;析构函数由于不能有参数,且只有一个,所以无法重载; ??如果子类想要重写父类的析构函数,那么只需要在父类的析构函数定义为虚函数。
七、new、delete 和 malloc、free的区别:
(1)malloc/free是c语言的库函数,new/delete是C++的运算符;运算符可以重载,库函数不行。 (2)它们都能在堆上申请动态内存和释放内存。 (3)new申请内存是自动计算大小,malloc申请内存需要程序员计算要申请的内存大小。 (4)new成功申请内存后,可以返回指定的类型指针。malloc成功申请内存后,返回的是(void*) 的指针,所以需要进行强制转换,这是不安全的。 (5)new操作符是从自由存储区(free store)上为对象动态分配内存;malloc是在堆上动态分配内存。 自由存储区可以是堆也可以是静态存储区,这都要看operator new在哪里为对象分配内存,大多是在堆上。
八、浅拷贝与深拷贝的区别
总结: B复制A,A变,B变,浅拷贝。 ?? ?B复制A,A变,B不变,深拷贝。 基本数据类型: 整型、浮点型、字符类型、bool类型等; 引用数据类型: 类、 接口类型、 数组类型、 枚举类型、 注解类型、 字符串型等。 可以理解为: 对于基本数据类型拷贝就是深拷贝,对于引用数据类型就是浅拷贝。
|