C++編程中new運算符的應用進修教程。本站提示廣大學習愛好者:(C++編程中new運算符的應用進修教程)文章只能為提供參考,不一定能成為您想要的結果。以下是C++編程中new運算符的應用進修教程正文
new運算符用作從自在存儲為 type-name 的對象或對象數組分派內存,並將已恰當分類的非零指針前往到對象。
[::] new [placement] new-type-name [new-initializer] [::] new [placement] ( type-name ) [new-initializer]
備注
假如不勝利,則 new 將前往零或激發異常;有關具體信息,請參閱 new 和 delete 運算符。 經由過程編寫自界說異常處置例程並挪用 _set_new_handler 運轉庫函數(以您的函數稱號作為其參數),可以更改此默許行動。
有關若何在托管堆上創立對象的信息,請參閱 gcnew。
應用 new 為 C++ 類對象分派內存時,將在分派內存後挪用對象的結構函數。
應用 delete 運算符可消除分派應用 new 運算符分派的內存。
以下示例先分派然後釋放一個二維字符數組,數組的年夜小為 dim x 10。 在分派多維數組時,除第一個維度以外的一切維度必需是盤算成果為正值的常量表達式;最左邊的數組維度可所以盤算成果為正值的任何表達式。 在應用 new 運算符分派數組時,第一個維度可為零 - new 運算符將前往一個獨一指針。
char (*pchar)[10] = new char[dim][10]; delete [] pchar;
type-name 不克不及包括 const、volatile、類聲明或列舉聲明。 是以,以下表達式長短法的:
volatile char *vch = new volatile char[20];
new 運算符不會分派援用類型,由於這些類型不是對象。
new 運算符沒法用於分派函數,但可用於分派指向函數的指針。 上面的示例為前往整數的函數分派然後釋放一個包括 7 個指針的數組。
int (**p) () = new (int (*[7]) ()); delete *p;
假如應用不帶任何額定參數的 new 運算符,並用 /GX、/EHa 或 /EHs 選項停止編譯,則編譯器將在結構函數激發異常時生成代碼來挪用運算符 delete。
以以下表描寫了 new 的語法元素:
placement
假如重載 new,則供給了一種傳遞附加參數的方法。
type-name
指定要分派的類型;它可所以內置類型,也能夠是用戶界說的類型。 假如類型標准異常龐雜,則可用括號將其括起來以強迫實行綁定次序。
initializer
為初始化對象供給值。 不克不及為數組指定初始值設定項。 僅當類具有默許結構函數時,new 運算符才會創立對象的數組。
示例
上面的代碼示例分派類 CName 的一個字符數組和一個對象,然後釋放它們。
// expre_new_Operator.cpp // compile with: /EHsc #include <string.h> class CName { public: enum { sizeOfBuffer = 256 }; char m_szFirst[sizeOfBuffer]; char m_szLast[sizeOfBuffer]; public: void SetName(char* pszFirst, char* pszLast) { strcpy_s(m_szFirst, sizeOfBuffer, pszFirst); strcpy_s(m_szLast, sizeOfBuffer, pszLast); } }; int main() { // Allocate memory for the array char* pCharArray = new char[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 = new CName; pName->SetName("Firstname", "Lastname"); // Deallocate memory for the object delete pName; pName = NULL; }
假如應用 new 運算符的放置新情勢(帶有參數和分派年夜小的情勢),假如結構函數激發異常,則編譯器不支撐 delete 運算符的放置情勢。 例如:
// expre_new_Operator2.cpp // C2660 expected class A { public: A(int) { throw "Fail!"; } }; void F(void) { try { // heap memory pointed to by pa1 will be deallocated // by calling ::operator delete(void*). A* pa1 = new A(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 (...) { } } int main() { A a; }
初始化應用 new 運算符分派的對象
可選的 initializer 字段包括在 new 運算符的語法中。 如許便可以應用用戶界說的結構函數來初始化新對象。 有關若何履行初始化的具體信息,請參閱初始值設定項。 以下示例演示若何將初始化表達式與 new 運算符一路應用:
// expre_Initializing_Objects_Allocated_with_new.cpp class Acct { public: // Define default constructor and a constructor that accepts // an initial balance. Acct() { balance = 0.0; } Acct( double init_balance ) { balance = init_balance; } private: double balance; }; int main() { Acct *CheckingAcct = new Acct; Acct *SavingsAcct = new Acct ( 34.98 ); double *HowMuch = new double ( 43.0 ); // ... }
在此示例中,應用 CheckingAcctnew 運算符分派了 對象,但未指定默許初始化。 是以,挪用了類的默許結構函數 Acct()。 然後,以雷同的方法分派了對象 SavingsAcct,只不外將它顯式初始化為 34.98。 因為 34.98 是類型 double,是以挪用了采取該類型的參數的結構函數來處置初始化。 最初,將非類類型 HowMuch 初始化為 43.0。
假如對象是類類型,而且該類具有結構函數(如後面的示例所示),則僅當知足以下前提之一時,new 運算符能力初始化該對象:
初始值設定項中供給的參數與結構函數的參數分歧。
該類有一個默許結構函數(可在沒有參數的情形下挪用的結構函數)。
拜訪掌握和二義性掌握依據operator new多義性和應用特別成員函數的初始化中所述的規矩對 和結構函數履行。
在應用 new 運算符分派數組時,沒法對每一個元素履行顯式初始化;只挪用了默許結構函數(假如有)。 有關具體信息,請參閱默許參數。
假如內存分派掉敗(operator new 的前往值為 0),則不履行初始化。 這可避免測驗考試初始化不存在的數據。
與函數挪用一樣,不決義初始化表達式的盤算次序。 另外,您不該期望這些表達式能在履行內存分派前完整盤算。 假如內存分派掉敗,而且 new 運算符前往零,則能夠不會完整盤算初始值設定項中的某些表達式。
應用 new 運算符分派的對象的生計期
在加入分派有 new 運算符的對象的界說規模時,將不會燒毀這些對象。 因為 new 運算符將前往指向其所分派的對象的指針,是以法式必需應用適合的規模界說指針能力拜訪這些對象。 例如:
// expre_Lifetime_of_Objects_Allocated_with_new.cpp // C2541 expected int main() { // Use new operator to allocate an array of 20 characters. char *AnArray = new char[20]; for( int i = 0; i < 20; ++i ) { // On the first iteration of the loop, allocate // another array of 20 characters. if( i == 0 ) { char *AnotherArray = new char[20]; } } delete [] AnotherArray; // Error: pointer out of scope. delete [] AnArray; // OK: pointer still in scope. }
在下面的示例中,指針 AnotherArray 一旦超越規模,將沒法再刪除對象。
new 的任務方法
allocation-expression(包括 new 運算符的表達式)履行三類操作:
定位並保存要分派的對象的存儲。 此階段完成後,將分派准確的存儲量,但它還不是對象。
初始化對象。 初始化完成後,將為成為對象的已分派存儲顯示足夠的信息。
前往指向派生自 new-type-name 或 type-name 的指針類型的對象的指針。 法式應用此指針來拜訪比來分派的對象。
new 運算符挪用函數 operator new。 關於任何類型的數組和不屬於 class、struct 或 union 類型的對象,挪用全局函數 ::operator new 來分派存儲。 類類型對象可基於每一個類界說其本身的 operator new 靜態成員函數。
當編譯器碰到用於分派 type 類型的對象的 new 運算符時,它將收回對 type::operator new( sizeof( type ) ) 的挪用;或許,假如不存在用戶界說的 operator new,則挪用 ::operator new( sizeof( type ) )。 是以,new 運算符可認為對象分派准確的內存量。