C++编程中new运算符的使用学习教程
2026/4/29 4:58:22 网站建设 项目流程

备注
如果不成功,则 new 将返回零或引发异常;有关详细信息,请参阅 new 和 delete 运算符。 通过编写自定义异常处理例程并调用 _set_new_handler 运行库函数(以您的函数名称作为其参数),可以更改此默认行为。
有关如何在托管堆上创建对象的信息,请参阅 gcnew。
使用 new 为 C++ 类对象分配内存时,将在分配内存后调用对象的构造函数。
使用 delete 运算符可解除分配使用 new 运算符分配的内存。
以下示例先分配然后释放一个二维字符数组,数组的大小为 dim x 10。 在分配多维数组时,除第一个维度之外的所有维度必须是计算结果为正值的常量表达式;最左侧的数组维度可以是计算结果为正值的任何表达式。 在使用 new 运算符分配数组时,第一个维度可为零 - new 运算符将返回一个唯一指针。

1

2

char(*pchar)[10] =newchar[dim][10];

delete[] pchar;

type-name 不能包含 const、volatile、类声明或枚举声明。 因此,以下表达式是非法的:

1

volatilechar*vch =newvolatilechar[20];

new 运算符不会分配引用类型,因为这些类型不是对象。
new 运算符无法用于分配函数,但可用于分配指向函数的指针。 下面的示例为返回整数的函数分配然后释放一个包含 7 个指针的数组。

1

2

int(**p) () =new(int(*[7]) ());

delete*p;

如果使用不带任何额外参数的 new 运算符,并用 /GX、/EHa 或 /EHs 选项进行编译,则编译器将在构造函数引发异常时生成代码来调用运算符 delete。
以下列表描述了 new 的语法元素:
placement
如果重载 new,则提供了一种传递附加参数的方式。
type-name
指定要分配的类型;它可以是内置类型,也可以是用户定义的类型。 如果类型规范非常复杂,则可用括号将其括起来以强制实施绑定顺序。
initializer
为初始化对象提供值。 不能为数组指定初始值设定项。 仅当类具有默认构造函数时,new 运算符才会创建对象的数组。
示例
下面的代码示例分配类 CName 的一个字符数组和一个对象,然后释放它们。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

// expre_new_Operator.cpp

// compile with: /EHsc

#include <string.h>

classCName {

public:

enum{

sizeOfBuffer = 256

};

charm_szFirst[sizeOfBuffer];

charm_szLast[sizeOfBuffer];

public:

voidSetName(char* pszFirst,char* pszLast) {

strcpy_s(m_szFirst, sizeOfBuffer, pszFirst);

strcpy_s(m_szLast, sizeOfBuffer, pszLast);

}

};

intmain() {

// Allocate memory for the array

char* pCharArray =newchar[CName::sizeOfBuffer];

strcpy_s(pCharArray, CName::sizeOfBuffer,"Array of characters");

// Deallocate memory for the array

delete[] pCharArray;

pCharArray = NULL;

// Allocate memory for the object

CName* pName =newCName;

pName->SetName("Firstname","Lastname");

// Deallocate memory for the object

deletepName;

pName = NULL;

}

如果使用 new 运算符的放置新形式(带有参数和分配大小的形式),如果构造函数引发异常,则编译器不支持 delete 运算符的放置形式。 例如:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

// expre_new_Operator2.cpp

// C2660 expected

classA {

public:

A(int) {throw"Fail!"; }

};

voidF(void) {

try{

// heap memory pointed to by pa1 will be deallocated

// by calling ::operator delete(void*).

A* pa1 =newA(10);

}catch(...) {

}

try{

// This will call ::operator new(size_t, char*, int).

// When A::A(int) does a throw, we should call

// ::operator delete(void*, char*, int) to deallocate

// the memory pointed to by pa2. Since

// ::operator delete(void*, char*, int) has not been implemented,

// memory will be leaked when the deallocation cannot occur.

A* pa2 =new(__FILE__, __LINE__) A(20);

}catch(...) {

}

}

intmain() {

A a;

}

初始化使用 new 运算符分配的对象
可选的 initializer 字段包含在 new 运算符的语法中。 这样就可以使用用户定义的构造函数来初始化新对象。 有关如何执行初始化的详细信息,请参阅初始值设定项。 以下示例演示如何将初始化表达式与 new 运算符一起使用:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

// expre_Initializing_Objects_Allocated_with_new.cpp

classAcct

{

public:

// Define default constructor and a constructor that accepts

// an initial balance.

Acct() { balance = 0.0; }

Acct(doubleinit_balance ) { balance = init_balance; }

private:

doublebalance;

};

intmain()

{

Acct *CheckingAcct =newAcct;

Acct *SavingsAcct =newAcct ( 34.98 );

double*HowMuch =newdouble( 43.0 );

// ...

}

在此示例中,使用 CheckingAcctnew 运算符分配了 对象,但未指定默认初始化。 因此,调用了类的默认构造函数 Acct()。 然后,以相同的方式分配了对象 SavingsAcct,只不过将它显式初始化为 34.98。 由于 34.98 是类型 double,因此调用了采用该类型的参数的构造函数来处理初始化。 最后,将非类类型 HowMuch 初始化为 43.0。
如果对象是类类型,并且该类具有构造函数(如前面的示例所示),则仅当满足以下条件之一时,new 运算符才能初始化该对象:
初始值设定项中提供的参数与构造函数的参数一致。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询