目录 Table of Contents
在堆中创建对象
我们可以在什么地方创建对象
-
全局变量区
Person p;
比如把这个代码放到函数外面的时候, 就会在全局变量区域创建对象 -
栈
void Max() { Person p; }
写到函数里面, 就是在堆栈中分配, 什么时候调用这个函数, 什么时候就创建对象, 一旦函数执行完毕, 这个对象的空间也就没有了.
-
堆, new delete
在堆中创建对象 :
Person* p = new Person();
释放对象占用的内存 :
delete p;
在堆中创建对象_
我们之前学到过一个函数 malloc()
, 这个函数申请的空间就是在堆中分配的
我们可以通过 new
关键字来在堆中创建对象
语法是我们先定义一个 Person 类的指针, 然后 p 为指针的名字, 然后 new 后面跟上构造函数
Person 类定义如下:
class Person
{
private:
int x;
int y;
public:
Person()
{
printf("Person()执行了\n");
}
Person(int x, int y)
{
printf("Person(int x, int y)执行了 \n");
this->x = x;
this->y = y;
}
~Person()
{
printf("~Person()执行了\n");
}
};
我们这里定义了两个构造函数, 如果你想使用无参数的, 就这样使用 : Person* p = new Person();
如果你想创建对象的时候给它赋值, 你可以选择使用第二个构造函数, 就像这样给它两个参数即可 : Person* p = new Person(1, 2);
在堆中申请内存, 一旦用完了之后, 需要把它释放出来, C 语言中是 free()
函数来释放内存, 在 C++ 中我们使用 delete
关键字释放对象空间
new delete 的本质
现在我们来看看 new
和 delete
两个关键字到底做了什么事情
通过运行结果猜测 : new 关键字除了在堆内存中申请空间创建对象之外, 还要调用它的构造函数, delete 关键字除了释放内存之外, 还要调用它的析构函数
现在我们看汇编代码观察一下, new 先调用了 windows 提供的 HeapAlloc 申请了一块内存, 然后调用了它的构造函数, 结论就是 new 这个关键词相当于就是 malloc 函数加上构造函数
delete 请自行分析
new[] / delete[]
如果你要在堆中申请一个数组, 你就需要使用 new[]
关键字
-
用 C 和 C++ 的方式分别在堆中申请一个 int 数组:
C :
int* p = (int*)malloc(sizeof(int)*10);
free(p);
C++ :
int* p = new int[10];
delete(p);
-
分别用 C 和 C++ 在堆中申请 Class 类型数组:
C :
int* p = (Person*)malloc(sizeof(Person)*10);
free(p);
C++ :
Person* p = new Person[10];
delete[] p;
基本类型两种是没有区别的, 如果你是定义的是自己的类的话, 这两种方式是有区别的
malloc 函数方式申请 Class 类型数组, 仅仅是给我们分配空间, 并不会调用构造函数, new 关键字不光是在堆中申请十个对象的空间, 对于每个对象, 它都会调用一次构造函数
同样, free 方式是只管释放空间, 并不会调用析构函数, delete 方式不光释放空间, 还会调用析构函数.
- delete 和 delete[] 有什么区别 ?
Person* p = new Person[10];
delete p;
比如说这样我创建的是十个对象, 但是我删除的时候没有加中括号, 我们运行观察汇编发现, 只有一个析构函数执行了, 并且程序出错了
区别就出来了, 如果你不加中括号的话, 它最后只删除第一个对象, 只调用第一个对象的析构函数
简单总结 : 如果我们只创建一个对象, 我们可以创建的时候使用 new, 删除的时候使用 delete; 如果你要创建多个对象, 比如创建一个对象数组, 那么创建的时候应该是用 new[], 删除的时候使用 delete[].