何问起C++教程 - 引言 - C++语言基础
C++创建对象使用或者不使用new的异同
C++在创建对象的时候一般有以下两种方式,一种使用new关键字,一种不使用。

假如类名为HtTestNew

HtTestNew m_test;//第一种方式

HtTestNew* pTest = new HtTestNew();//第二种方式

这两种方法都可以实例化一个对象,但是这两种方法有很大的区别,区别在于对象内容所在的内存空间不同。
请看以下代码的例子:
#include <iostream>

class HtTestNew
{
private:
int ID;
public:
HtTestNew(int ID);
~HtTestNew();
};

HtTestNew::HtTestNew(int ID)
{
this->ID = ID;
}

HtTestNew::~HtTestNew()
{
std::cout << "对象 " << this->ID << " 执行析构函数" << std::endl;

}
void HovertreeTest1()
{
HtTestNew test(1);//创建对象1,不使用new,离开作用域自动调用析构函数

}

void HovertreeTest2(){
HtTestNew* pTest = new HtTestNew(2);//创建对象2,使用new
//delete pTest; //注释掉,故意不删除,不会执行析构函数
}

void HovertreeTest3() {
HtTestNew* pTest = new HtTestNew(3);//创建对象3,使用new
delete pTest; // new的东西记得删除,会执行析构函数
}

int main()
{
std::cout << "Hello Hovertree!\n";
HovertreeTest1();
HovertreeTest2();
HovertreeTest3();
std::cout << "Hi Hovertree!\n";
std::cout<<std::endl;

}
运行效果如下图:

从运行结果中,我们可以得出在不使用new创建对象时,对象的内存空间是在栈中的,其作用范围只是在函数内部,函数执行完成后就会调用析构函数。出了作用域就会自动失效。

而使用new创建对象是创建在堆中的,必须要程序员手动的去管理该对象的内存空间。在delete之前不会失效。如果不需要这个对象,必须使用delete释放。 new创建类对象需要指针接收。使用new实例化对象会调用相应的构造函数。delete对象会调用相应的析构函数。

补充:
一般而言,内存的分配方式有三种
(1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。
(2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束后在将这些局部变量的内存空间回收。在栈上分配内存空间效率很高,但是分配的内存容量有限。
(3) 从堆上分配的。程序在运行的时候用 malloc 或 new 申请任意多少的内存(容量大小只受物理内存限制),程序员自己负责在何时用 free 或 delete 释放内存。


栈内存是程序自动管理的,不能使用 delete 删除在栈上创建的对象;堆内存由程序员管理,对象使用完毕后可以通过 delete 删除。在实际开发中,new 和 delete 往往成对出现,以保证及时删除不再使用的对象,防止无用内存堆积。

栈(Stack)和堆(Heap)是 C/C++ 程序员必须要了解的两个概念
收藏 列表

评论: