好久没有用c++,转一个c++注意点
一?? 編程設計
???? 1.將程序劃分為多個子系統,包括子系統間的接口和依賴關系、子系統間的數據流、在各子系統間的來回輸入輸出、以及總的線程模型。
???? 2.各個子系統的具體細節,包括進一步細分的類、類層次體系、數據結構、算法、特定的線程模型和錯誤處理。
二?? 設計流程
???? 1.需求:功能需求和性能需求。
???? 2.設計步驟
?????? (1)把程序劃分為通用功能子系統,并明確子系統的接口和交互。
?????? (2)把這些子系統列在一個表中,并表示出子系統的高層行為或功能、子系統向其它子系統提供的接口,及此子系統使用了其他子系統的哪些接口。
?????? (3)選擇線程模型:確定使用多少個線程,明確線程的交互并為共享數據指定加鎖機制。
?????? (4)為每個子系統指定層次體系
?????? (5)為每個子系統指定類、數據結構、算法和模式
?????? (6)為每個子系統指定錯誤處理(系統錯誤 + 用戶錯誤),指定是否使用異常
三?? C++ 的設計原則
???? 1.抽象:將接口與實現相分離
???? 2.重用:代碼重用和思想重用
四?? 對象關系
???? 1.has-a 關系(聚集)
???? 2.is-a? 關系(繼承)
???? 3.組織對象層次體系:
????? (1)將類按有意義的功能加以組織。
????? (2)將共同的功能放到超類中,從而支持代碼重用。
????? (3)避免子類過多的覆蓋父類的功能。
五?? 重用設計
???? 1.建立可重用的代碼結構
????? (1)避免將無關或邏輯上分離的概念混在一起
????? (2)把程序劃分為子系統
????? (3)使用類層次體系來分離邏輯概念
????? (4)使用聚集來分離邏輯概念
????? (5)對通用數據結構和算法使用模板
????? (6)提供適當的檢查和防護
六?? 設計易于使用的接口
???? 1.開發直觀的接口
???? 2.不要遺漏必要的功能
???? 3.提供簡潔的接口
????? (1)消除重復的接口
????? (2)只提供所需的功能
????? (3)適當的限制庫的使用
???? 4.提供文檔和注釋
????? (1)公共的文檔應指定行為,而不是底層實現
七?? 設計通用的接口
???? 1.提供多種方法來完成同一功能
???? 2.提供定制能力
八?? 協調一般性和通用性
???? 1.提供多個接口
???? 2.優化常用功能
九?? 代碼注釋
???? (1)前綴注釋
??????? * 文件/類名
??????? * 最后一次修改時間
?????? ?* 原作者
??????? * 文件所實現特性的編號 (特性 ID)
??????? * 版權信息
??????? * 文件/類的簡要描述
????????* 未完成的特性
??????? * 已知的 bug
???? (2)注釋示例
??????? /*
???????? * Watermelon.cpp
???????? *
???????? * $Id: Watermelon.cpp,v 1.6 2004/03/10 12:52:33 klep Exp $
???????? *
???????? * Implements the basic functionality of a watermelon. All
?????? ? * unit are expressed in terms of seeds per cubic centimeter
???????? * Watermelon theory is based on the white paper "Alogorthms
??????? ?* for Watermelon Processing."
???????? *
???????? * The following code is (c)copyright 2004. FruitSoft, Inc.
???????? * All right reserved
???????? */
十?? 編寫代碼
???? 1.類定義在 C++ 中是一條語句,因此必須以分號結束。
???? 2.:: 指作用域解析操作符。
???? 3.在棧和堆上使用對象的區別
?????? (1)在棧上創建對象
????????? SpreadsheetCell myCell, anotherCell;
?????? (2)在堆上使用對象
????????? SpreadsheetCell *myCellp = new SpreadsheetCell();
?????? (3)如果用 new 來分配一個對象,用完該對象時要用 delete 來釋放
???? 4.C++ 程序員通常把構造函數稱為 "ctor"
???? 5.使用構造函數
?????? (1)在棧上使用構造函數
????????? SpreadsheetCell myCell(5);
?????? (2)在堆上使用構造函數
????????? SpreadsheetCell *myCell = new SpreadsheetCell(5);
????????? delete myCell;
?????? (3)不要嘗試從類的一個構造函數調用另一個構造函數
???? 6.使用默認構造函數
?????? (1)在棧上使用構造函數
????????? SpreadsheetCell myCell;? //right
????????? SpreadsheetCell myCell();//wrong
?????? (2)在棧上創建對象時,要去掉默認構造函數的小括號
?????? (3)在堆上使用默認構造函數
????????? SpreadsheetCell *myCellp = new SpreadsheetCell();
?????? (4)什么時候需要使用構造函數
????????? SpreadsheetCell cells[3];//fails comilation without default ctor
??????? ?SpreadsheetCell *myCellp = new SpreadsheetCell[10];//alse fails
?????? (5)使用初始化列表
????????? 1)初始化列表允許在創建數據成員的同時完成數據成員的初始化
????????? 2)使用初始化列表的情況
??????數據成員?????????????????????????????????????????解釋
????? ------------------------------------------------------------------
??????const 數據成員????????????????????????????? 必須在創建時提供值
??????引用數據成員?????????????????????????????? 引用無法獨立存在
??????沒默認構造函數的對象成員?????? 對象成員無法初始化
????? 沒有默認構造函數的超類?????????? 見后面?
????? ------------------------------------------------------------------
???? 7.對象的撤銷
?????? (1)析構函數僅用于釋放內存或釋放其他資源是一個不錯的想法
???? 8.淺復制與深復制
?????? (1)淺復制:只是從源對象直接將數據成員復制或賦值到目標對象
?????? (2)深復制:非淺復制
?????? (3)只要在類中動態分配了內存,就應該編寫自己的復制構造函數來提供內存的深復制
?????? (4)在對一個對象進行賦值前,必須先釋放此對象的所有動態分配的內存
?????? (5)只要類會動態分配內存,就需要編寫析構函數、復制構造函數、賦值操作符
?????? (6)禁止對象賦值,可將復制構造函數與賦值操作符聲明為私有成員
?????? (7)不必為私有復制構造函數和賦值操作符提供實現,編譯器不要求
十一 精通類和對象
???? 1.不能在靜態方法中訪問非靜態數據成員
???? 2.保證一個對象不會修改數據成員,可用 const 來標記
???? 3.保證一個方法不會修改數據成員,可用 const 來標記
?????? (1)在類定義中的聲明 double getValue() const;
?????? (2)在源文件中的實現
????????? double Spreadsheet::getValue() const
???????? {
?????????? ?return this.mValue;
???????? }
???? 4.非 const 對象可以調用 const 和非 const 方法,const 對象只能調用const 方法
???? 5.應將所有不會修改對象的方法都聲明為 const,并在程序中使用 const對象引用
???? 6.將變量置為 mutable,這樣編譯器允許在 const 方法中修改這個變量
???? 7.C++ 不允許僅基于方法的返回類型而重載一個方法名
???? 8.默認參數:從最右參數開始的連續參數表
???? 9.只能在方法聲明中指定默認參數,在定義中并不指定
???? 10一個構造函數的所有參數都有默認值,此函數會作為默認構造函數
???? 11能利用默認參數做到的事情,利用方法重載也可以做,用你最熟悉的
???? 12內聯:將方法體或函數體直接插入到代碼調用處(相當于 #define 宏的安
?????? 全版本),內聯示例如下:
?????? (1)在類的源文件(SpreadsheetCell.cpp)
?????? inline double SpreadsheetCell::getValue() const
?????? {
?????????? mNumAccess++;
????????? ?return mValue;
?????? }
?????? (2)或在類的聲明文件中直接實現此方法而不用 inline 關鍵字
?????? //SpreadsheetCell.h
?????? double getValue() const (mNumAccesses++; return mValue;}
???? 13友元可以訪問指定類中的 protected 和 private 數據成員和方法
?????? (1)聲明友元類
????????? class SpreadsheetCell
???????? ?{
????????? ?? public:
??????????????? ?friend class Spreadsheet;
?????????????? ?//code omitted here
????????? };
?????? (2)聲明友元方法
????????? class SpreadsheetCell
??????? ?{
???????????? public:
??????????????? ?friend bool checkSpreadsheetCell();
??????????????? ?//code omitted here
?????? ? };
十二 C++ 中的繼承機制
???? 1.超類指針(引用)在引用子類時,了類仍然會保留它們覆蓋的方法。而在
?????? 強制類型轉換成超類對象時,子類會失去它們的獨有特性。覆蓋方法和子
?????? 類數據的丟失稱為切割。
???? 2.作為一條經驗,要把所有的方法都用 virtual 聲明 (包括析構函數,但
?????? 是不包括構造函數) 來避免因遺漏關鍵字 virtual 而產生的相關問題。
???? 3.virtual 用法示例:
?????? class Sub : public Super
?????? {
?????????? public:
??????? ? ?Sub();
??????? ? ?virtual void someMethod();
??????? ? ?virtual void someOtherMethod();
?????? }
???? 4.要把所有的析構函數都用 virtual 聲明
???? 5.強制類型轉換
?????? (1)靜態轉換 static_cast<type>
????????? 示例:
????????? Sub* mySub = static_cast<Sub*>(inSuper);
?????? (2)動態轉換 dynamic_cast<type>
????????? 示例:
??????? ? Sub* mySub = dynamic_cast<Sub*>(inSuper);
??????? ? if (mySub == NULL)
???????? {
????????? ??? //proceed to access sub methods on mySub
??????? ?}
??
?? 注意:如果對指針不能進行動態類型轉換,指針則為 NULL, 而不是指
?? 向無意義的數據。
???? 6.進行向上強制類型轉換時,要使用指向超類的指針或引用來避免切割問題。
???? 7.純虛方法與抽象基類
?????? (1)純虛方法: 在類定義中顯示未定義的方法。
?????? (2)抽象類: 含有純虛方法的類(不能實例化)。
?????? (3)純虛方法語法定義: 在類定義中簡單的設置方法等于 0,在 cpp 文件
????????? 中不要編寫其實現代碼。
?? 示例:
?? class SpreadsheetCell
?? {
?????? public:
?????????? SpreadsheetCell();
?????????? virtual ~SpreadsheetCell();
?????????? virtual void set(const std::string instring) = 0;
????????? ?virtual std::string getString() const = 0;
?????};
???? 8.定制類型轉換函數
?????? (1)double 類型轉換成 string 類型
????????? #include <iostream>
????????? #include <sstream>
??
????????? double inValue;
????????? string myString;
?????? ?? ostringstream ostr;
?????? ?? ostr << inValue;
?????? ?? myString = ostr.str();
?????? (2)string 類型轉換成 double 類型
????????? #include <iostream>
?????? ?? #include <sstream>
??
?????? ?? double myDouble;
?????? ?? string inString;
??
?????? ?? istringStream istr(inString);
?????? ?? istr >> myDouble;
????? ?? if (istr.fail())
??????? {
???????? ? myDouble = 0;
???? ?? }
???? 9.使用預編譯指令避免重復包含頭文件
?????? #ifndef _TEST_H_
?????? #define _TEST_H_
?????? // include header files here??????
?????? // other code omitted here
?????? #endif
??
十三 覆蓋方法的特殊情況
???? 1.在 C++ 中不能覆蓋靜態方法。
?????? (1)不能同時用 virtual 和 static 聲明一個方法。
?????? (2)在對象上可以調用 static 方法,但 static 方法只存在于類中。
十四 利用模板編寫通用代碼
???? 1.模板相關概念
?????? (1)類模板: 存儲對象的容器或數據結構。
?????? (2)模板的語法:
????????? template <typename T>
????? ?? class Grid
????? ?? {
??????????? ?public:
???????????????? Grid(int inWidth, int inHeight);
???????????? ??? Grid(const Grid<T>& src);
??????????? ? ?? Grid<T>& operator=(const Grid<T>& rhs);
???????????? ??? T& getElementAt(int x, int y);
???????????????? const T& getElementAt(int x, int y);
???????????? ??? void setElementAt(int x, int y, const T& inElem);
????? ?????? protected:
??????????? ???? void copyFrom(const Grid<T>& src);
???????????? ??? T** mCells;
??????? };
??????? (3)語法解釋
??????????? template <typename T> : 指在類型 T 上定義的模板。
??????????? Grid<T> : Grid 實際上是模板名。
??????? ??? Grid<T> : 將作為類模板中的類名。
?(4)模板定義(實現)
??? template <typename T>
??? Grid<T>::Grid(int inWidth, int inHeight)
??? {
??????? mCells = new T* [mWidth];
??????? for (int i = 0; i < mWidth; i++)
??????? {
??????????? mCells[i] = new T[mHeight];
??????? }
??? }
?(5)模板實例化
??? Grid<int> myIntGrid;
十五 C++ 中的一些疑難問題
???? 1.引用
?????? (1)定義: 另一個變量的別名, 對引用的修改會改變其所指向的變量。
?????? (2)引用變量必須在創建時就初始化。
????????? int? x = 3;?? // right
?????? ?? int& xRef = x;// right
?????? ?? int& emptyRef;//wrong
????????? 注: 類的引用數據成員可在構造函數的初始化列表中初始化。
?????? (3)不能創建指向未命名值的引用(const 常量值除外)
????????? int& unnameRef = 5;????? //does not compile
?????? ?? const int& unnameRef = 5;//works as expect
?????? (4)修改引用: 引用總是指向初始化時指定的那個變量。
????????? int x = 3, y = 4;
?????? ?? int& xRef = x;
?????? ?? xRef = y; // change x value to 4, doesn't make refer to y;
?????? ?? xRef = &y; // doesn't compile, type not match
???????? 注: 引用指向的變量在初始化之后不能再改變, 只能改變此變量的值
?????? (5)指針引用和引用指針
????????? //指針引用示例(指向指針的引用)
????????? int*? intP;
?????? ?? int*& ptrRef = intP;
?????? ?? ptrRef = new int;
????? ?? *ptrRef = 5;
????? ?? 注:不能聲明指向引用的引用, 也不能聲明引用指針(指向引用的指針)
????? ?? int x = 3;
????? ?? int& xRef = x;
????? ?? int&& xDoubleRef = xRef; // not compile
????? ?? int&* refPtr = &xRef; // not compile
??
?????? (6)傳引用vs傳值
????????? 1)效率。復制大對象和結構要花費很長時間。
????????? 2)正確性。不是所有的對象都允許傳值或正確的支持深復制。
????????? 3)不想修改原對象,又利用以上兩優點,可在參數前加 const。
???????? 4)對簡單內置類型(如int或double)要傳值,其它所有情況可傳引用。
?????? (7)引用vs指針
????????? 1)引用讓程序清晰,易于理解。
?????? ?? 2)引用比指針安全,不存在無效的引用,不需要明確解除引用。
????????? 3)除非需要動態分配內存或在其它地方要改變或釋放指針指向的值,否則都應使用引用而非指針。
????
???? 2.疑難字 const
?????? (1)const 變量
????????? 使用 const 來聲明變量,對不能對其修改,以保護變量。
?????? (2)const 指針
??? ?? //不能改變指針指向的值
????????? const int* ip;
????????? ip = new int[10];
?????? ?? ip[4] = 5; // not compile
??????? 或
?????? ?? int const* ip;
?????? ?? ip = new int[10];
?????? ?? ip[4] = 5; // not compile
?
????????? //不能改變指針自身
????????? int* const ip;
?????? ?? ip = new int[10]; // not compile
?????? ?? ip[4] = 5;
???? ? ? //既不能改變指針也不能改變指針指向的值
????? ?? const int* const ip = NULL;(無用的指針)
????????? 注: const 可以放在類型前也可以放在類型后
??
?????? (3)const 應用規則
????????? const 應用于其左則的第一項。
?????? (4)把對象參數傳遞時,默認的做法是把傳遞 const 引用。
?????? (5)const 方法
????????? 用 const 標識類方法,可以防止方法修改類中不可變的數據成員。
???? 3.關鍵字 static
?????? (1)關于連接: C++ 中的每個源文件是獨立編譯的,得到的對象連接在一
????????? 起。
?????? (2)外部連接: 一個源文件中每個名字(如函數或全局變量)對其它源文件
????????? 是可用的。
?????? (3)內部連接: 一個源文件中每個名字(如函數或全局變量)對其它源文件
????????? 是不可用的。內部連接也叫靜態連接。
?????? (4)函數和全局變量默認是外部連接。
?????? (5)聲明前加 static 可指定為內部連接。
???? 4.關鍵字 extern
?????? (1)作用: 與 static 相對,用來為位于它前面的名字聲明外部連接。
?????? (2)extern 用法
????????? // AnotherFile.cpp
????? ?? extern int x; // 只是聲明 x 為外部連接而不分配內存
????? ?? int x = 3;??? //顯示定義以分配內存
??????? 或
????????? extern int x = 3;//聲明和定義一起完成
????????? //FirstFile.cpp
????? ?? extern int x;
????? ?? cout << x << endl;
????? 5.強制類型轉換
???? ?(1)const_cast<type> 去除變量的常量性。
????? 示例:
????? void g(char* str)
????? {
??????? ? // body omitted here
??????}
????? void f(const char* str)
????? {
??????? ? g(const_cast<char*>(str));
??????????// other code omitted here
????? }??????
?(2)static_cast<type> 顯示的完成 C++ 語言支持的轉換。
??? 示例:
??? int x = 3;
??? double result = static_cast<double>(i) /10;
??? 注: static_cast 進行類型轉換時并不完成運行時類型檢查。
?(3)dynamic_cast<type>
??? 1)對類型強制轉換完成運行時類型檢查。
??? 2)對指針轉換失敗時會返回 NULL。
??? 3)對引用轉換失敗時會拋出 bad_cast 異常。
?
6.函數指針
??????? (1)定義: 把函數地址作為參數,可以像變量一樣使用。
?????? ?(2)定義函數指針: typedef bool(*YesNoFcn) (int, int);
??????? (3)用法示例
?????????? //定義函數指針類型
?????????? typedef string(*YesNoFcn)(int, int);
?????? ??? void test(int value1, int values2, YesNoFcn isFunction)
????????? {
???????????? cout << isFunction(value1, value2);
??????????}
?????????string intEqual(int intItem1, int intItem2)
?????????{
??????????? return (intItem1 == intItem2) ? "match" : "not match";
???????? }
???? ??? //使用函數指針
????? ??? test(1, 1, &intEqual);
???? ??? 注: & 是可選的
十六 C++ 中的 I/O 操作
???? 1.使用流
?????? (1)每個輸入流都有一個相關聯的源,每個輸出流都有一個相關聯的目的。
?????? (2)cout 和 cin 都是在 C++ 的 std 命名空間中預定義的流實例。
?????? (3)流的三種類型:
????????? 1)控制臺輸入輸出流。
????????? 2)文件流。
?????? ?? 3)字符串流。
?????? (4)輸出流
????????? 1)輸出流在頭文件 <ostream> 中定義,輸入流在 <istream> 中定義<iosream> 中定義了輸入輸出流。
?????? ?? 2)cout 和 cin 指控制臺輸入輸出流。
????????? 3)<< 操作符是使用輸出流的最簡單的方法。
????????? 4)流其它的輸出方法
???????????? 1)put() 和 wirte()
?????????????2)flush() 刷新輸出
?
????????? 5)處理輸出錯誤
??????? ???? 1)cout.good()? 流是否處于正常的可用狀態。
???????????? 2)cout.bad()?? 流輸出是否發生了錯誤。
??????? ???? 3)cout.fail()? 如果最近的操作失敗則返回 true
??????? ???? 4)cout.clear() 重置流的錯誤狀態
?? 6)輸出控制符
???? 1)endl???????? 輸出回車并刷新其緩沖區
???? 2)hex oct dec? 以十六/八/十進制輸出
???? 3)setw???????? 設置輸出數值數據時的字段占位符
???? 4)setfill??? 設置填充空位的占位符
?????? (5)輸入流
????????? 1)>> 輸入流操作符
????????? 2)輸入方法
????????????? 1)get()??? 僅僅返回流中的下一個字符
????????????? 2)unget()??? 引起流回退一個位置
???????????? ?3)peek()??? 預覽下一個值
????????????? 4)getline()??? 從輸入流中取一行數據
???????? ?3)處理輸入錯誤
???????????? 1)good()
???????????? 2)eof()
?????? (6)字符串流
????????? 1)<ssteam>??? 定義了字符串流的頭文件
????? ?? 2)ostringstream? 字符串輸出流
???????? 3)istringstream? 字符串輸入流
?????? (7)文件流
????????? 1)<fstream>????? 定義了文件流的頭文件
?????? ?? 2)ifstream??? 文件輸入流
?????? ?? 3)ofstream??? 文件輸出流
?????? ?? 4)seek()??? 定位流的位置
?????? ?? 5)tell()??? 查詢流當前的位置
?????? (8)鏈接流
????????? 1)定義: 在任何輸入流與輸出流之間建立連接,一旦訪問就刷新輸出。
?????? ?? 2)實現: 用輸入流的 tie() 方法
?????? ?? 3)示例
??????????? #include <iostream>
????? ???? #inlcude <fstream>
????? ???? #include <string>
?????????? main()
???????????{???????????
??????????????? ifstream inFile("input.txt");
?????????????? ofstream outFile("output.txt");
????
?????? ???????? //set up a link between inFile and outFile.
?????? ???????? inFile.tie(&outFile);
????????????? ?string nextToken;
???? ??????? ? inFile >> nextToken;
???????? }
十七 C++ 中的異常
???? 1.拋出和捕獲異常
?????? (1)<exception> 定義異常類的頭文件。
?????? (2)拋出異常對象 throw exception()
?????? (3)向量的使用(整型)
???? ?? vector<int> myInts;
???? ?? for (int i = 0; i < 10; i++)
???? ?? {
???????????? myInts.push_back(i);// 增加元素
??????????? ?cout << myInts[i];
???? ?? }
?????? (4)string 風格的字符串轉換成 C 風格的字符串
????????? string myString = "string style string";
????????? char* cStyleStrng = myString.c_str();
?????? (5)捕獲運行時異常
????????? try
????? ?? {
??????????? ...
?????? ?? }
????????? catch (const runtime_error& e)
????? ?? {
?????????? ...
?????????}
?????? (6)拋出和捕獲無效參數異常
????????? throw invalid_argument("");
????? ?? try
????????? {
??????????? ...
?????? ?? }
????????? catch (const invalid_argument& e)
????????? {
??????? ???? ...
????????? }
????? ?? 注: runtime_error 和 invalid_argument 定義在頭文件<stdexcept> 中
?????? (7)匹配任何異常(...)
????????? try
?????? ?? {
??????????? // code omitted here
?????? ?? }
?????? ?? catch (...)
?????? ?? {
?????? ???? // code omitted
????????? }
???????? 注: 不建議使用這種方式
?????? (8)使用拋出列表
????????? 1)拋出列表: 一個函數或方法能拋出的異常列表
?????? ?? 2)必須為函數聲明和實現都提供拋出列表
?????? ?? 3)沒有拋出列表就可以拋出任何異常
???????? 4)空的拋出列表不允許拋出任何異常
?????? (9)在覆蓋方法中修改參數列表
????????? 1)從列表中刪除異常
?????? ?? 2)增加超類拋出列表中異常的子類
????????? 3)不能完全刪除拋出列表
?????? (10)顯示異常消息
?????????? 可調用 exception 或子類的 what() 方法顯示捕獲到的異常消息
?????????? 示例:
?????? ??? try
?????????? {
?????????????? ...
?????????? }
?????? ??? catch (const exception& e)
?????????? {
?????????????? cerr << e.what() << endl;
????????????? ?exit(1);
?????????? }
????????????
?????? (11)多態地捕獲異常
?????????? 1)在多態地捕獲異常時,要確保按引用捕獲異常。如果按值捕獲異常,就會遇到切割問題,丟失對象的信息。
?????? ??? 2)按引用捕獲異常可以避免不必要的復制開銷
?????? (12)如果異常處理不夠仔細,就會導致內存和資源泄漏
?????????? 示例
?????? ??? func ()
????? ??? {
????????? ? string str1;
??????????? string* str2 = new string();
??????????? throw exception();
??????????? delete str2;???? // 內存泄漏
????????? }
?????? (13)使用智能指針防止內存泄漏
?????????? #include <memory> // 定義智能指針的頭文件
?????? ??? using namespace std;
?????????? func ()
?????????? {
??????????? ?? string str1;
?????????????? // 智能指針,不用自己手動釋放
????? ??????? auto_ptr<string> str2(new string("hello"));
??????????? ? throw exception();
?????????? }
?????? (14)處理內存分配錯誤
?????????? 1)new 和 new [] 分配內存失敗默認拋出 bad_alloc 異常
?????? ??? 2)可用 try/catch 捕獲異常處理內存分配失敗
?????????? 3)示例:
???????????? try
???????????? {
???????????????? ptr = new int[numInts];
?????????????}
?????????????catch (bad_alloc& e)
??????????? {
????????????? cerr << "Unable to alloc memory!" << endl;
?????????? ?? return ;
????????????}
???????? 或
????? ??? 1)用 new(nothrow) 在內存分配失敗時返回 NULL 來處理
????????? 2)示例:
???????????? ptr = new(nothrow) int[numInts];
????? ????? if (ptr == NULL)
??????????? {
?????????????? cerr << "Unable to alloc memory!" << endl;
??????????? ?? return;
??????????? }
???????? 或
?????????? 1)用 set_new_handler() 回調函數定制分配失敗時的行為
?????? ??? 2)示例
????????????? void myNewHandler()
?????? ????? {
???????????? ?? cerr << "Unable to allocate memory!" << endl;
???????????? ?? abort(); // 終止程序 <cstdlib>
???????????? }
????????????
???????????? #include <new>
??????????? #include <cstdlib>
??????????? #include <iostream>
????? ????? using namespace std;
?????
??????????? int main(int argc, char** argv)
?????????? {
?????????????? new_handler oldHandler = set_new_handler(myNewHandler);
?????????? ?? // code omitted here
????????? ?? set_new_handler(oldHandler);
???? ??????? return (0);
?????????}
轉載于:https://www.cnblogs.com/cloudseawang/archive/2008/04/08/1142299.html
總結
以上是生活随笔為你收集整理的好久没有用c++,转一个c++注意点的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到考试第一名是什么意思
- 下一篇: 梦到抱男婴儿有什么预兆