C++表达式new与delete知识详解

2020-01-06 15:13:48王冬梅

c. 动态创建对象的值初始化(value-initialize)

这种值初始化不能用于变量定义,而只能用于动态创建方式。


string *ps2 = new string(); // initialized to empty string
int *pi = new int(); // pi points to an int value-initialized to 0

值初始化表明程序员想要做初始化,但并未提供特定的初值。实际上,对于提供了默认构造函数的类类型(如string),没有必要对其对象进行值初始化:无论程序是明确地不初始化还是要求进行值初始化,都会自动调用其默认构造函数初始化该对象。值初始化真正有用的是对于内置类型。另外需要注意的一点是,值初始化的 () 语法必须置于类型名后面,而不是变量名后面,否则得到的是一个函数声明,如下:


int myValue(); // not value-initialized int variable, but a function named myValue
int *myPtr = new int(); // correct! a value-initialized int object

对于没有默认构造函数的类类型,无论是变量定义还是动态创建对象都必须采用显式初始化。

3. 撤销对象

动态创建的对象用完后,程序员必须显式地将该对象占用的内存返还给自由存储区。C++提供了delete表达式释放指针所指向的地址空间。

delete myPtr;
上述语句释放 myPtr 指向的 int 型对象所占用的内存。

C++没有明确定义如何释放指向不是用 new 分配的内存地址的指针。此外,编译器通常不能断定一个指针究竟指向什么类型的对象,因此如果调用delete 企图释放指向栈内存地址的指针时,编译器并不会报错,但请尽量不要依赖于该未定义的行为。

在C++中 delete 一个零值指针是合法且安全的,但实际上毫无意义。

悬垂指针(dangling pointer)

删除了指针所指向的对象后,该指针变成悬垂指针。悬垂指针指向曾经存放对象的内存,但该对象实际已经不存在了。悬垂指针往往导致程序错误,并且很难检测。因此,在调用delete 释放指针所指对象内存后应该立刻将指针置零。

4. Const 对象的动态分配和回收

const 对象,必须在定义阶段或动态创建阶段进行初始化,并且初始化之后其值不能再修改。

与其他 const 对象的地址一样,由于 new 返回的地址上存放的是 const 对象,因此该地址只能赋给指向 const 的指针。