程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 詳解C++中new運算符和delete運算符的應用

詳解C++中new運算符和delete運算符的應用

編輯:關於C++

詳解C++中new運算符和delete運算符的應用。本站提示廣大學習愛好者:(詳解C++中new運算符和delete運算符的應用)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解C++中new運算符和delete運算符的應用正文


C++ 支撐應用 new 和 delete 運算符靜態分派和釋放對象。這些運算符為來自稱為“自在存儲”的池中的對象分派內存。 new 運算符挪用特別函數 operator new,delete 運算符挪用特別函數 operator delete。
在 Visual C++ .NET 2002 中,尺度 C++ 庫中的 new 功效將支撐 C++ 尺度中指定的行動,假如內存分派掉敗,則會激發 std::bad_alloc 異常。
假如內存分派掉敗,C 運轉庫的 new 函數也將激發 std::bad_alloc 異常。
假如您仍須要 C 運轉庫的 new 的非激發版本,請將您的法式鏈接到 nothrownew.obj。然則,當您鏈接到 nothrownew.obj 時,尺度 C++ 庫中的 new 將不復興感化。

挪用 new 運算符
在法式中碰到以下語句時,它將轉換為對函數 operator new 的挪用:

char *pch = new char[BUFFER_SIZE];

假如要求針對零字節存儲,operator new 將前往一個指向分歧的對象的指針(即對 operator new 的反復挪用將前往分歧的指針)。假如分派要求沒有足夠的內存,則 operator new 將前往 NULL 或激發異常(有關具體信息,請參閱 )。
可以編寫測驗考試釋放內存的例程偏重試分派;有關具體信息,請參閱 _set_new_handler。有關恢復計劃的更多具體信息,請參閱以下主題:處置內存缺乏的情形。
下表中描寫了 operator new 函數的兩個規模。
operator new 函數的規模
運算符 規模 ::operator new 全局 class-name ::operator new 類

operator new 的第一個參數的類型必需為 size_t(STDDEF.H 中界說的類型),而且前往類型一直為 void *。
在應用 new 運算符分派內置類型的對象、不包括用戶界說的 operator new 函數的類類型的對象和任何類型的數組時,將挪用全局 operator new 函數。在應用 new 運算符分派類類型的對象時(個中界說了 operator new),將挪用該類的 operator new。
為類界說的 operator new 函數是靜態成員函數(是以,它不克不及是虛函數),該函數隱蔽此類類型的對象的全局 operator new 函數。斟酌 new 用於分派內存並將內存設為給定值的情形:

// spec1_the_operator_new_function1.cpp
#include <malloc.h>
#include <memory.h>

class Blanks
{
public:
 Blanks(){}
 void *operator new( size_t stAllocateBlock, char chInit );
};
void *Blanks::operator new( size_t stAllocateBlock, char chInit )
{
 void *pvTemp = malloc( stAllocateBlock );
 if( pvTemp != 0 )
  memset( pvTemp, chInit, stAllocateBlock );
 return pvTemp;
}
// For discrete objects of type Blanks, the global operator new function
// is hidden. Therefore, the following code allocates an object of type
// Blanks and initializes it to 0xa5
int main()
{
 Blanks *a5 = new(0xa5) Blanks;
 return a5 != 0;
}

用括號包括的供給給 new 的參數將作為 Blanks::operator new 參數傳遞給 chInit。然則,全局 operator new 函數將被隱蔽,從而招致以下代碼生成毛病:

Blanks *SomeBlanks = new Blanks;

在 Visual C++ 5.0 和晚期版本中,應用 new 運算符分派的非類類型和一切數組(不管其類型能否為 class)一直應用全局 operator new函數。
從 Visual C++ 5.0 開端,編譯器支撐類聲明中的成員數組 new 和 delete 運算符。例如:

// spec1_the_operator_new_function2.cpp
class MyClass
{
public:
 void * operator new[] (size_t)
 {
  return 0;
 }
 void operator delete[] (void*)
 {
 }
};

int main() 
{
 MyClass *pMyClass = new MyClass[5];
 delete [] pMyClass;
}

處置內存缺乏
對掉敗的內存分派停止測試可以經由過程以下編碼完成:

// insufficient_memory_conditions.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
#define BIG_NUMBER 100000000
int main() {
 int *pI = new int[BIG_NUMBER];
 if( pI == 0x0 ) {
  cout << "Insufficient memory" << endl;
  return -1;
 }
}

處置掉敗的內存分派請求的其他辦法:編寫自界說恢復例程來處置此類掉敗,然後經由過程挪用 _set_new_handler 運轉時函數來注冊您的函數。
delete 運算符
可以使用 delete 運算符釋放應用 new 運算符靜態分派的內存。delete 運算符挪用 operator delete函數,該函數將內存釋放回可用池。應用 delete 運算符也會招致挪用類析構函數(假如有)。
存在全局和類規模的 operator delete函數。只能為給定類界說一個 operator delete函數;假如界說了該函數,它會隱蔽全局 operator delete函數。一直為一切類型的數組挪用全局 operator delete函數。
全局 operator delete函數(假如已聲明)采取 void * 類型的單個參數,該參數包括指向要釋放的對象的指針。前往類型是 void(operator delete 沒法前往值)。類成員 operator delete 函數有兩種情勢:

void operator delete( void * );
void operator delete( void *, size_t );

給定類中只存在後面兩個變量中的一個。第一個情勢依照為全局 operator delete 描寫的那樣運轉。第二個情勢采取兩個參數,第一個是指向要釋放的內存塊的指針,第二個是要釋放的字節的數目。當基類中的 operator delete 函數用於刪除派生類的對象時,第二個情勢特殊有效。
operator delete 函數是靜態的;是以它不克不及是虛函數。 operator delete 函數屈服拜訪掌握,如成員拜訪掌握中所述。
以下示例顯示旨在記載內存的分派和釋放的用戶界說的 operator new 和 operator delete 函數:

// spec1_the_operator_delete_function1.cpp
// compile with: /EHsc
// arguments: 3
#include <iostream>
using namespace std;

int fLogMemory = 0;  // Perform logging (0=no; nonzero=yes)?
int cBlocksAllocated = 0; // Count of blocks allocated.

// User-defined operator new.
void *operator new( size_t stAllocateBlock ) {
 static int fInOpNew = 0; // Guard flag.

 if ( fLogMemory && !fInOpNew ) {
  fInOpNew = 1;
  clog << "Memory block " << ++cBlocksAllocated
   << " allocated for " << stAllocateBlock
   << " bytes\n";
  fInOpNew = 0;
 }
 return malloc( stAllocateBlock );
}

// User-defined operator delete.
void operator delete( void *pvMem ) {
 static int fInOpDelete = 0; // Guard flag.
 if ( fLogMemory && !fInOpDelete ) {
  fInOpDelete = 1;
  clog << "Memory block " << cBlocksAllocated--
   << " deallocated\n";
  fInOpDelete = 0;
 }

 free( pvMem );
}

int main( int argc, char *argv[] ) {
 fLogMemory = 1; // Turn logging on
 if( argc > 1 )
  for( int i = 0; i < atoi( argv[1] ); ++i ) {
   char *pMem = new char[10];
   delete[] pMem;
  }
 fLogMemory = 0; // Turn logging off.
 return cBlocksAllocated;
}

後面的代碼可用於檢測“內存溢出”,即在自在貯存平分配但從未釋放過的內存。若要履行此檢測,則應從新界說全局 new 和 delete 運算符以盤算內存的分派和釋放。
從 Visual C++ 5.0 開端,編譯器支撐類聲明中的成員數組 new 和 delete 運算符。例如:

// spec1_the_operator_delete_function2.cpp
// compile with: /c
class X {
public:
 void * operator new[] (size_t) {
  return 0;
 }
 void operator delete[] (void*) {}
};

void f() {
 X *pX = new X[5];
 delete [] pX;
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved