内部类
定义:
- 如果一个类在另一个类的内部,这个类就被称为内部类。
- 内部类是一个独立的类,不属于外部类,外部类对内部类没有任何访问的权限。
//构造一个内部类
class A
{
public:
class B
{
void fun(const A& a)
{//}
};
private:
};
int main ()
{
A::B b; //构造内部类
b.fun(A());
return 0;
}
注:内部类可以看做外部类的友元类,内部类可以通过外部类的对象参数访问外部类的所有成员;但外部类不是内部类的友元类。
特性:
- 内部类可以定义在外部类的public、private、protected中;
- 内部类可以直接访问外部类的static成员,不需要外部类的对象/类名;
- sizeof(外部类)= 外部类,与内部类无关。
封装
定义: C++通过类,将一个对象的属性与行为结合在一起,就是将属于该对象的所有东西打包在一起;通过访问限定符有选择性的将部分功能开放与其他对象进行交互(通俗理解为:成员变量和成员函数都放在类里面,想给外部访问的就定位公有,否则就定为私有或保护,这本质上是一种比较好的管理方式)。
内存分布
虚拟内存分段展示如下:
- 栈:函数调用会建立栈帧,栈帧主要存:局部变量、参数、返回值等;(向下生长)
- 堆:动态申请、释放内存;(向上生长);
- 静态区:存static变量、全局变量;
- 常量区:存常量、程序编译出的指令。
注:
- 向下生长:指后申请的地址比先申请的地址小;
- 向上生长:指在一般情况下,后申请的地址比先申请的地址大。
动态内存管理方式
我们先讨论C语言中malloc、calloc、realloc三种动态开辟内存方法:
- malloc:是在堆上原地动态开空间;
- calloc:在堆上动态开空间+初始化为0;等于malloc+memset;
- realloc:针对已有的空间进行扩容(原地扩容或异地扩容)。
由于C语言内存管理方式在C++中有些地方使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。
//申请数组
//malloc申请5个类型为int的数组
int* p1 = (int*) malloc(sizeof(int)*5);
free(p1);
//new申请5个类型为int的数组
int* p2 = new int [5];
delete[] p2;
//申请单个对象
//malloc申请单个int对象
int* p1 = (int*)malloc(sizeof(int));
free(p1);
//new申请单个int对象
int* p2 = new int;
delete int;
malloc和new的异同:
- 对于内置类型:malloc、new没有任何差别,只是用法不太一样;
- 对于自定义类型:C语言中,malloc只是开辟空间;C++中,new是开辟空间+构造函数初始化,delete是析构函数的清理+释放空间。
小结:
- 若是在C++中申请内置类型的对象或数组,malloc和new没什么区别;
- 在C++中,对于自定义类型,malloc/free和new/delete区别很大,一般建议尽量使用new/delete