目录
引入
(1) 和 (2) 的最大不同
栈变量(局部变量)
堆变量
new的讲解
概述
典型的用法
概述
(7) 的意思
(8) 的意思
(2) 的意思
总结
引入
(1) 和 (2) 的最大不同
Tesk t3 = Tesk(1,2,3); // (1)
Test* t7 = new Test(1,2,3); // (2)
- (1) 是在栈上创建了一个对象,属于局部变量。
- (2) 是在堆上创建了一个对象,属于堆变量。
栈变量(局部变量)
void Temp();
int main()
{
int a = 1; // (3)
Temp();
return 0;
}
void Temp()
{
int* b = NULL; // (4)
}
- 普通创建的变量被分配在栈(后进先出)上,称为栈变量(如 (1) 、(3)、(4) )。
- 栈变量的生命周期是临时的。从它被创建的时候生,作用域结束的时候灭(自动释放)。
- 由于栈变量是在栈上创建的,因此在非特殊情况下,最晚创建的变量将会最先被消灭。
堆变量
int c = 2; // (5)
int main()
{
int* d = (int*)malloc(sizeof(int)); // (6)
int* e = new int; // (7)
int* f = new int(1); // (8)
return 0;
}
- 堆变量就是全局、静态、用 malloc 、new 等类似的关键字申请堆空间的变量(如 (5)、(6)、(7) 、(8) )(与关键字有关的一般都是指针)。
- 堆变量分配的空间不会自动释放,若在程序中没有手动释放堆变量,它将一直占用系统内存。
- 关于 malloc 与 new 的异同此处不展开,可参考博客 C/C++动态内存管 。
new的讲解
概述
- 当我们使用关键字 new 在堆上动态创建一个对象时,它实际上做了三件事( 只考虑申请空间成功的情况 ):
1)申请一块新的、对应类型大小的内存空间(不会自动释放),创建该类型的对象。
2)调用该类的构造函数,对对象进行初始化。
3)返回指向该对象的指针。
- 如果我们创建的是简单类型的变量(无构造函数的类型的变量),那么第二步会被省略。
- 想要释放该空间需要手动删除,即书写 delete(指针变量名); 。否则内存将会在 main 函数结束时才会被释放掉,造成内存的泄露。
典型的用法
概述
类型名* 指针变量名 = new 该对象的构造函数名( parameter1, ...);
- 由于类型名=它的构造函数名故上述格式可写为:
类型名* 指针变量名 = new 类型名( parameter1, ...);
int* e = new int; // (7)
int* f = new int(1); // (8)
delete(e); // 不用的时候记得要手动释放内存
delete(f); // 不用的时候记得要手动释放内存
(7) 的意思
- 使用关键字 new 在堆上申请一段 int 类型大的 空间(不会自动释放),创建一个 int 类型 的 对象 。
调用 int 的无参构造函数(相当于什么也没有做)。- 返回该 对象(int 类型) 的 指针 给指针变量 e 。
(8) 的意思
- 使用关键字 new 在 堆 上申请一段 int 类型大的 空间(不会自动释放),创建一个 int 类型 的 对象 。
- 调用 int 的单参构造函数(即该对象 = 括号的1)。
- 返回该 对象(int 类型) 的 指针 给指针变量 f ( 由于上一步,此时 *f = 1 )。
Tesk t3 = Tesk(1,2,3); // (1)
Test* t7 = new Test(1,2,3); // (2)
delete(t7); // 不用的时候记得要手动释放内存
(2) 的意思
- 使用关键字 new 在 堆 上申请一段 Tesk 类型大的 空间(不会自动释放),创建一个 Tesk 类型 的 对象 。
-
调用 Tesk 的3参构造函数 。
-
返回该 Tesk 类型的对象 的 指针 给指针变量 t7 。
总结
- 熬夜对身体有害。