C++何时需要new对象,new对象和定义对象的区别:
一、String str;
- 不用new的内存区域是在栈,会自动分配空间,一般在局部变量时使用,函数结束后会自动释放空间,
- 定义对象就是申明对象(静态)
- str有系统创建并释放,你不要担心会出现内存泄露,但是生命期只有在本区域的大括号内,出了大括号就没用了。
- 构造函数应可以保证被执行,因为程序退出通路很多,你必须是正常的退出才可能保证析构函数被调用,当你创建一个类对象时,构造函数就自动运行创建自己,当你不在需要这个对象时,析构函数自动把自己结束了(析构系统调用)。
二、String *str1 = new String;
- 用new的内在区域是在堆,要自己手动分配空间,使用完后要手动释放空间,另外栈中空间的分配一般在编译时就知道大小了,而如果要在运行时分配空间,就要使用堆了,
- new 就是创建对象的实例并为它分配足够的空间(动态)
- str1是指针,要自己释放,用不好很危险,用好了功能强大,因为他可以赋值给全局的变量,一下子从局部变量变成全局变量,还能把对象作为函数返回值。
- 指针指向这个对象,那么这个指针几乎可以调用对象里的所有成员函数,看你想调谁,调析构函数就执行析构函数(自己调用)
使用new动态分配和初始化对象
在自由空间分配的内存是无名的,因此,new无法为其分配的对象命名,而是返回一个指向该对象的指针:
int *pi = new int; // new int 相当于int *p ,不同的是new int开辟的内存在堆区。(大致这样理解)
此new表达式在自由空间构造一个int型对象,并返回指向该对象的指针。
默认情况下,动态分配的对象是默认初始化的,这意味着内置类型或组合类型的对象的值将是未定义的,而类类型对象将用默认构造函数进行初始化:
string *ps = new string;// 初始化为空string
int *pi = new int;// pi指向一个未初始化的int
我们可以使用直接初始化方式初始化一个动态分配的对象,也可以使用传统的构造方式,在新标准下,也可以使用列表初始化(使用花括号):
int *pi = new int(1024);//pi指向动态分配的对象,其值为1024
string *ps = new string(10, '9'); // *ps 为"999999999"
//vector 有10个元素,值一次是0-9
vector<int> *pv = new vector<int> {1,2,3,4,5,6,7,8,9};
也可以为动态分配的对象进行值初始化,只需在类型名之后加一对空括号即可:
string *pa = new string;// 默认初始化为空string
string *pe = new string() // 值初始化为空string
int *pa = new int;//默认初始化,*pa的值未定义
int *pe = new int();// 值初始化为0,*pe的值为0
下面看一个完整的例子:
class A
{
public:
A(int i) :a(i){}
private:
int a;
};
int main()
{
A* example = new A(1);
}
new operator实际上执行了以下三个步骤:
1、调用operator new分配内存(后面要说的第二种new),如果类本身定义了operator new,那么会调用类自己的operator new,而不是全局的;
2、调用A的构造函数A::A(int);
3、返回相应的指针
总结:
1.只有变量才不需要New.
2.对象是引用型的,变量则是传值型的
3.变量是栈存储,而对象一般是堆
我们的推荐是:只要能在栈上创建对象,就在栈上创建;否则的话,如果你不得不需要更长的生命周期,只能选择堆上创建