亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++中new的用法及說明

 更新時間:2022年11月07日 09:43:26   作者:見牛羊  
這篇文章主要介紹了C++中new的用法及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

C++ new的用法

知識點小結

new其實就是告訴計算機開辟一段新的空間,但是和一般的聲明不同的是,new開辟的空間在堆上,而一般聲明的變量存放在棧上。

通常來說,當在局部函數中new出一段新的空間,該段空間在局部函數調用結束后仍然能夠使用,可以用來向主函數傳遞參數。

另外需要注意的是,new的使用格式,new出來的是一段空間的首地址。所以一般需要用指針來存放這段地址。

具體的代碼如下:

#include <iostream>
using namespace std;
 
int example1()
{
  //可以在new后面直接賦值
  int *p = new int(3);
  //也可以單獨賦值
  //*p = 3;
 
  //如果不想使用指針,可以定義一個變量,在new之前用“*”表示new出來的內容
  int q = *new int;
  q = 1;
  cout << q << endl;
 
  return *p;
}
 
int* example2()
{
  //當new一個數組時,同樣用一個指針接住數組的首地址
  int *q = new int[3];
  for(int i=0; i<3; i++)
    q[i] = i;
 
  return q;
}
 
struct student
{
  string name;
  int score;
};
 
 
student* example3()
{
  //這里是用一個結構體指針接住結構體數組的首地址
  //對于結構體指針,個人認為目前這種賦值方法比較方便
  student *stlist = new student[3]{{"abc", 90}, {"bac", 78}, {"ccd", 93}};
 
  return stlist;
}
 
 
 
int main()
{
  int e1 = example1();
  cout <<"e1: "<< e1 << endl;
 
  int *e2 = example2();
  for(int i=0; i<3; i++)
    cout << e2[i] << " ";
  cout << endl;
 
 
  student *st1 = example3();
 
  for(int i=0; i<3; i++)
    cout << st1[i].name << " " << st1[i].score << endl;
 
 
 
  return 0;
}

new的三種使用方法

概念

在C++中new的三種用法包括:plain new, nothrow new 和 placement new。

plain new 就是我們最常使用的new的方式,在C++中的定義如下:

1 void* operator new(std::size_t) throw(std::bad_alloc); ?
2 void operator delete( void *) throw();

plain new在分配失敗的情況下,拋出異常std::bad_alloc而不是返回NULL,因此通過判斷返回值是否為NULL是徒勞的。

nothrow new 是不拋出異常的運算符new的形式。nothrow new在失敗時,返回NULL。定義如下:

1 void * operator new(std::size_t, const std::nothrow_t&) throw();
2 void operator delete(void*) throw();

placement new 意即“放置”,這種new允許在一塊已經分配成功的內存上重新構造對象或對象數組。placement new不用擔心內存分配失敗,因為它根本不分配內存,它做的唯一一件事情就是調用對象的構造函數。定義如下:

1 void* operator new(size_t, void*);
2 void operator delete(void*, void*);

palcement new 的主要用途就是反復使用一塊較大的動態(tài)分配的內存來構造不同類型的對象或者他們的數組。placement new構造起來的對象或其數組,要顯示的調用他們的析構函數來銷毀,千萬不要使用delete。

示例

  • plain new
char *getMemory(unsigned long size) ??
{ ? ?
? ? char * p = new char[size]; ??
? ? return p;?
} ??
void main(void) ??
{
? ? try{ ??
? ? ? ? char * p = getMemory(1000000); ? ?// 可能發(fā)生異常
? ? ? ? // ... ??
? ? ? ? delete [] p; ??
? ? } ??
? ? catch(const std::bad_alloc &amp; ex) ??
? ? {
? ? ? ? cout &lt;&lt; ex.what();
? ? } ??
}
  • nowthrow new
void func(unsinged long length) ??
{
? ? unsinged char * p = new(nothrow) unsinged char[length]; ??
? ? // 在使用這種new時要加(nothrow) ,明示不使用異常處理 。
?
? ? if (p == NULL) ?// 因不拋異常,故定要檢查
? ? ? ? cout << "allocte failed !"; ??
? ? ? ? // ... ??
? ? delete [] p;
}
  • placement new
void main() ??
{ ?
? ? using namespace std; ??
? ? char * p = new(nothrow) char [4]; ??
? ? if (p == NULL) ??
? ? {
? ? ? ? cout << "allocte failed" << endl; ?
? ? ? ? exit( -1 );
? ? } ??
? ? // ... ??
? ? long * q = new (p) long(1000); ??
? ? delete []p; ? ?// 只釋放 p,不要用q釋放。
}

p和q僅僅是首址相同,所構建的對象可以類型不同。所“放置”的空間應小于原空間,以防不測。當”放置new”超過了申請的范圍,Debug版下會掛機,但Release版竟然能運行而不出錯!

該運算符的作用是:只要第一次分配成功,不再擔心分配失敗。

void main() ??
{
? ? using namespace std; ??
? ? char * p = new(nothrow) char [100]; ??
? ? if (p == NULL) ??
? ? { ?
? ? ? ? cout << "allocte failed" << endl;
? ? ? ? exit(-1);
? ? } ??
? ? long * q1 = new (p) long(100); ??
? ? // 使用q1 ?... ??
? ? int * q2 = new (p) int[100/sizeof(int)]; ??
? ? // 使用q2 ... ??
? ? ADT * q3 = new (p) ADT[100/sizeof(ADT)]; ??
? ? // 使用q3 ?然后釋放對象 ... ??
? ? delete [] p; ? ?// 只釋放空間,不再析構對象。
}

注意:使用該運算符構造的對象或數組,一定要顯式調用析構函數,不可用delete代替析構,因為placement new 的對象的大小不再與原空間相同。

void main() ??
{ ?
? ? using namespace std; ??
? ? char * p = new(nothrow) char [sizeof(ADT)+2]; ??
? ? if (p == NULL) ??
? ? { ?
? ? ? ? cout << "allocte failed" &lt;&lt; endl;
? ? ? ? exit(-1);?
? ? }?
? ? // ...?
? ? ADT * q = new (p) ADT;?
? ? // ...?
? ? // delete q; // 錯誤
? ? q->ADT::~ADT(); ?// 顯式調用析構函數,僅釋放對象
? ? delete [] p; ? ? // 最后,再用原指針來釋放內存
}

placement new 的主要用途就是可以反復使用一塊已申請成功的內存空間。這樣可以避免申請失敗的徒勞,又可以避免使用后的釋放。

特別要注意的是對于 placement new 絕不可以調用的delete, 因為該new只是使用別人替它申請的地方(只是個租房戶,不是房主。無權將房子賣掉)。釋放內存是nothrow new的事,即要使用原來的指針釋放內存。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • C++新特性詳細分析基于范圍的for循環(huán)

    C++新特性詳細分析基于范圍的for循環(huán)

    C++11這次的更新帶來了令很多C++程序員期待已久的for?range循環(huán),每次看到javascript,?lua里的for?range,心想要是C++能有多好,心里別提多酸了。這次C++11不負眾望,再也不用羨慕別家人的for?range了。下面看下C++11的for循環(huán)的新用法
    2022-04-04
  • VC++中內存對齊實例教程

    VC++中內存對齊實例教程

    這篇文章主要介紹了VC++中內存對齊的實現方法,具有很高的實用價值,需要的朋友可以參考下
    2014-08-08
  • C語言中實現KMP算法的實例講解

    C語言中實現KMP算法的實例講解

    KMP算法即字符串匹配算法,C語言中KMP可以避免指針回溯從而達到高效,接下來就來總結一下C語言中實現KMP算法的實例講解
    2016-06-06
  • 淺談C++函數聲明后面加throw()的作用(必看)

    淺談C++函數聲明后面加throw()的作用(必看)

    下面小編就為大家?guī)硪黄獪\談C++函數聲明后面加throw()的作用(必看)。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • C++常用函數之XML JSON格式轉換問題

    C++常用函數之XML JSON格式轉換問題

    XML在Json出現前應用很廣泛,靈活性好,應用語言也沒有限制,發(fā)展了這么長時間后xml標準已經很臃腫。這篇文章主要介紹了C++常用函數之XML JSON格式轉換問題,需要的朋友可以參考下
    2020-02-02
  • C語言中時間戳轉換成時間字符串的方法

    C語言中時間戳轉換成時間字符串的方法

    在PE格式里有個字段是文件的創(chuàng)建時間戳,我想把轉成字符串,今天小編給大家分享一段代碼,可以比較直觀的看出,需要的的朋友參考下
    2017-02-02
  • C語言數據結構與算法之單鏈表

    C語言數據結構與算法之單鏈表

    單鏈表是一種鏈式存取的數據結構,用一組地址任意的存儲單元存放線性表中的數據元素。本文將為大家介紹C語言中單鏈表的基本概念與讀取數據元素,需要的可以參考一下
    2021-12-12
  • C語言數組任意位置插入一個元素方法

    C語言數組任意位置插入一個元素方法

    這篇文章主要給大家分享C語言數組任意位置插入一個元素方法,
    2021-11-11
  • C語言簡明講解隊列的實現方法

    C語言簡明講解隊列的實現方法

    隊列(Queue)與棧一樣,是一種線性存儲結構,它具有如下特點:隊列中的數據元素遵循“先進先出”(First?In?First?Out)的原則,簡稱FIFO結構。在隊尾添加元素,在隊頭刪除元素
    2022-04-04
  • VS2019 Nuget找不到包的問題處理

    VS2019 Nuget找不到包的問題處理

    這篇文章主要介紹了VS2019 Nuget找不到包的問題處理,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03

最新評論