C++中有了malloc / free , 为什么还需要 new / delete
- malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。
- 对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。 对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。 由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。
- 因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,和一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。
C++有哪些性质
1、封装
隐藏对象的属性和实现细节,仅对外公开接口和对象进行交互,将数据和操作数据的方法进行有机结合。
2、继承
继承就是新类从已有类那里得到已有的特性。 类的派生指的是从已有类产生新类的过程。原有的类成为基类或父类,产生的新类称为派生类或子类
3、多态
多态就是多种形态,一个接口,多种方法,C++的多态分为静态多态与动态多态。静态多态就是重载,函数参数类型、个数或者顺序不同(返回值可相同可不同),因为在编译期决议确定,所以称为静态多态。在编译时就可以确定函数地址。动态多态就是通过继承重写基类的虚函数实现的多态,因为实在运行时决议确定,所以称为动态多态。运行时在虚函数表中寻找调用函数的地址。
C++中三种限定符的含义
- public:public表明该数据成员、成员函数是对所有用户开放的,所有用户都可以直接进行调用
- private:private表示私有,私有的意思就是除了class自己之外,任何人都不可以直接使用,私有财产神圣不可侵犯嘛,即便是子女,朋友,都不可以使用。
- protected:protected对于子女、朋友来说,就是public的,可以自由使用,没有任何限制,而对于其他的外部class,protected就变成private。
子类父类构造函数、析构函数调用顺序
定义一个对象时先调用基类的构造函数、然后调用派生类的构造函数;析构的时候恰好相反:先调用派生类的析构函数、然后调用基类的析构函数。
C++内存分配方式以及它们的区别
- 静态存储区域,内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。
- 栈,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。
- 堆,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。
- 文字常量区,常量字符串就是放在这里, 程序结束后由系统释放 。
- 程序代码区,存放函数体的二进制代码。
指针和引用的区别
- 引用是别名,指针是地址
- 指针可以被重新赋值以指向另一个对象,但是引用则总是在初始化时被指定的对象,以后不能改变,但是指向的内容可以改变。
- 引用必须被初始化,指针不必。
- 引用不能为NULL,指针可以为NULL
- 引用变量内存单元保存的是被引用变量的地址
- “sizeof 引用" = 指向变量的大小 , “sizeof 指针”= 指针本身的大小
- 指针自增指向下一个地址,而引用是对变量本身的值的增加
- 指针可以有多级,但是引用只能是一级,例如int **p是合法的,而 int &&a是不合法的
const的作用
- 常量指针还是指针常量:const只对它左边的东西起作用,唯一的例外就是const本身就是最左边的修饰符,那么它才会对右边的东西起作用。根据这个规则来判断,m1应该是常量指针(即,不能通过m1来修改它所指向的内容。);而m2应该是指针常量(即,不能让m2指向其他的内存模块)。
- 声明常量
- 修饰形参,普通形参加不加const限定符对实参没有影响,引用形参和指针形参前面没有const限定符时,实参必须是非const的,而前面有const限定符时对实参也没有什么影响。
- 修饰函数的返回值
- 修饰函数体,在类中将成员函数修饰为const表明在该函数体内,不能修改对象的数据成员而且不能调用非const函数。为什么不能调用非const函数?因为非const函数可能修改数据成员,const成员函数是不能修改数据成员的,所以在const成员函数内只能调用const函数。
static的作用
- 修饰全局变量时,表明一个全局变量只对定义在同一文件中的函数可见。
- 修饰局部变量时,表明该变量的值不会因为函数终止而丢失,在函数运行时初始化。
- 修饰函数时,表明该函数只在同一文件中调用。
- 修饰类的数据成员,表明对该类所有对象这个数据成员都只有一个实例。即该实例归 所有对象共有。在编译时初始化,其在类实例化之前就存在了。
- 用static修饰不访问非静态数据成员的类成员函数。这意味着一个静态成员函数只能访问它的参数、类的静态数据成员和全局变量,
STL里的list和vector是怎么实现的
vector内部是一片连续的空间,有三个指针,一个指向数据段头,一个指向数据段尾,还有一个指向可用空间的尾部。然后vector插入时候是怎么插入的,如果是插入一个数据时空间不够