C++建立物件的兩種方式
C++建立物件有兩種方式,在棧上建立物件(Objects on the Stack)和在堆上建立物件(Objects on the Heap)。
假設我們有以下的類:
1 #include <string> 2 using std::string; 3 4 class SpreadsheetCell{ 5 public: 6 void setValue(double inValue); 7 double getValue(); 8 void setString(string inString); 9 string getString();10 11 protected: 12 string doubleToString(double inValue); 13 double stringToDouble(string inString); 14 15 double mValue; 16 string mString; 17 };
以及如下的cpp檔案:
1 #include "stdafx.h" 2 #include "SpreadsheetCell.h" 3 #include <iostream> 4 #include <sstream> 5 6 using namespacestd; 7 8 void SpreadsheetCell::setValue(double inValue){ 9 mValue = inValue; 10 mString = doubleToString(mValue); 11 } 12 13 double SpreadsheetCell::getValue(){ 14 return mValue; 15 } 16 17 void SpreadsheetCell::setString(string inString){ 18 mString = inString; 19 mValue = stringToDouble(mString);20 } 21 22 string SpreadsheetCell::getString(){ 23 return mString; 24 } 25 26 string SpreadsheetCell::doubleToString(double inValue){ 27 ostringstream ostr; 28 ostr<<inValue; 29 return ostr.str(); 30 } 31 32 double SpreadsheetCell::stringToDouble(string inString){ 33 double temp; 34 35 istringstream istr(inString); 36 37 istr>>temp; 38 if(istr.fail() || !istr.eof()){ 39 return (0); 40 } 41 42 return temp; 43 }
1. 在棧上建立物件(Objects on the Stack):
語法:
1 ClassName ObjName1, ObjName2(parameter01)// But never OjbName()
顧名思義,用這種方法建立的物件,記憶體分配到棧裡(Stack)。使用 “.” 非 “->” 呼叫物件的方法。當程度離開物件的使用範圍(如方法結束,一個程度塊的最後{}),範圍內的棧中的物件會自動刪除,記憶體自動回收。這是建立物件最簡單的方式,與“int x = 0;”是一樣的。如下面例子:
SpreadsheetCell myCell, anotherCell; myCell.setValue(6); anotherCell.setValue(myCell.getValue()); cout << “cell 1: “ << myCell.getValue() << endl; cout << “cell 2: “ << anotherCell.getValue() << endl; //destroy: int main(int argc, char** argv) { SpreadsheetCell myCell(5); if (myCell.getValue() == 5) { SpreadsheetCell anotherCell(6); } // anotherCell is destroyed as this block ends. cout << “myCell: “ << myCell.getValue() << endl; return (0); } // myCell is destroyed as this block ends. //destroy in reverse order: { SpreadsheetCell myCell2(4); SpreadsheetCell anotherCell2(5); // myCell2 constructed before anotherCell2 } // anotherCell2 destroyed before myCell2
2.在堆上建立物件(Objects on the Heap):
語法:
ClassName *obj1 = new ClassName(); ClassName *obj2 = new ClassName(parameter); delete obj1; delete obj2;
用這種方法建立的物件,記憶體分配到堆裡(Heap)。一般使用“->” 呼叫物件的方法。箭頭操作符”->"將解引用(dereferencing*)和成員使用(member access.)結合起來,下例兩個輸出,效果等價:
1 int _tmain(int argc, _TCHAR* argv[]) 2 { 3 SpreadsheetCell *myCellp = new SpreadsheetCell(); 4 5 myCellp->setValue(3.7); 6 7 cout<<"cell 1: "<<myCellp->getValue()<<" "<<myCellp->getString()<<endl; 8 9 cout<<"cell 1: "<<(*myCellp).getValue()<<" "<<(*myCellp).getString()<<endl; 10 11 delete myCellp; 12 return 0; 13 }
在堆中的物件不會自動刪除,記憶體不會自動回收,所以new一個物件使用完畢,必須呼叫delete,釋放記憶體空間。也就是說,new和delete必須成對出現。
順便提提,記憶體的分配方式有三種
(1)從靜態儲存區域分配。記憶體在程式編譯的時候就已經分配好,這塊記憶體在程式的整個執行期間都存在。例如全域性變數,static 變數。
(2) 在棧上建立。在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執行結束後在將這些區域性變數的記憶體空間回收。在棧上分配記憶體空間效率很高,但是分配的記憶體容量有限。
(3) 從堆上分配的。程式在執行的時候用 malloc 或 new 申請任意多少的記憶體,程式設計師自己負責在何時用 free 或 delete 釋放記憶體。
參考:
Professional C++, chapter 8
相關推薦
java之執行緒建立的兩種方式,六種狀態和匿名內部類建立子類或實現類物件
一.匿名內部類建立子類或實現類物件 new Test(){} 相當於建立了Test類的子類物件 並且沒有類名 建立介面實現類 new 介面名() {};介面實現類的物件 注意 : new 後邊是類或者介面名 大括號內是類或者介面中的方法 public
C#利用WebClient 兩種方式下載文件
sys end adf ati stream pac pub 利用 static WebClient client = new WebClient(); 第一種 string URLAddress = @"http://files.cnblogs.com/x4646/tre
Java執行緒建立的兩種方式
package test; /** * 建立執行緒 * */ public class Demo1 { public static void main(String arg[]){
GitHub建立分支兩種方式
一:需求背景 1.1 開發新功能和修改bug一般新建分支,如果覺得可行,可以合併到master分支上. 二:建立方式 &nbs
SpringBoot學習筆記(二) SpringBoot專案建立的兩種方式
叄念 springboot 專案建立方式其實有多種,這裡我們主要介紹兩種方式: 當然這裡建議大家用方式一來建立,方式二用於理解 方式
JS 之函式定義 & 建立物件 三種方式
JS函式建立三種方式 JS建立物件三種方式 一、javaScript 函式建立的三種方式 <html> <head> <meta http-equiv="Content-Type" content="text/htm
java--(多執行緒建立的兩種方式Thread類和Runnable介面)
(一)繼承Thread類建立多執行緒----單執行緒下面的程式碼是一個死迴圈,但是不會執行main裡面的迴圈語句,而是run()裡面的語句,這是因為該程式是一個單執行緒程式,當呼叫MyThread類的run()方法時,遇到死迴圈,迴圈一直進行。因此,MyThread類的列印
redis儲存物件兩種方式對比
redis儲存物件結構的兩種方式使用redis string結構儲存物件序列化後的資料使用redis hash結構儲存物件,field為欄位名稱測試例子還是大家喜歡的使用者資訊public class
Gradle Plugin 的建立的兩種方式
# Gradle Plugin 外掛是一系列 Task 的組合。 ## 外掛可以用來幹嘛? 模組化構建指令碼的功能 公共的功能可以抽取出來成為外掛,可以供多個 build.gradle 使用,增加複用性。 ## 外掛的型別 指令碼外掛 是一個構建指令
建立物件五種方式&&new關鍵字和newInstance()方法的區別
轉載:http://www.kuqin.com/shuoit/20160719/352659.html 用最簡單的描述來區分new關鍵字和newInstance()方法的區別: newInstance: 弱型別。低效率。只能呼叫無參構造。 new: 強型別。相對高效。能呼叫
C++建立物件的兩種方式
C++建立物件有兩種方式,在棧上建立物件(Objects on the Stack)和在堆上建立物件(Objects on the Heap)。假設我們有以下的類: 1 #include <string> 2 using std::string; 3 4 class Spreadsheet
物件建立的三種方式和閉包的兩種常用場景--js
物件建立的三種方式 ①通過new關鍵字建立物件 var obj = new Object(); obj.name = 'daxue'; obj.age = 28; obj.fun = function(){ } alert(obj.age); ②
C++ 建立物件的三種方式
第一種和第二種沒什麼區別,一個隱式呼叫,一個顯式呼叫,兩者都是在程序虛擬地址空間中的棧中分配記憶體,而第三種使用了new,在堆中分配了記憶體,而棧中記憶體的分配和釋放是由系統管理,而堆中記憶體的分配和釋放必須由程式設計師手動釋放。採用第三種方式時,必須注意一下幾點問題: n
java反射class的三種方式,反射建立物件的兩種方式
反射中,欲獲取一個類或者呼叫某個類的方法,首先要獲取到該類的 Class 物件。 1、獲取Class物件 在 Java API 中,提供了獲取 Class 類物件的三種方法: 第一種,使用 Class.forName 靜態方法。 前提:已明確類的全路徑名。 第二種,
面向物件 建立物件的兩種方式
面向物件建立物件的兩種方式方法一:var obj={name:'zhangsan',age:20;};方法二:var obj=new Object();obj.name='zhangsan'; ****************************************
C:C語言前序建立二叉樹的兩種方式和前序遍歷二叉樹的方法
#include<stdio.h> #include<stdlib.h> typedef struct BiTreeNode { int data; struct BiTre
淺談建立物件的兩種方式
經常使用IDE不容易看出編譯和執行的明顯區別,因為像eclipse這樣的開發工具會自動進行編譯。當你建立一個類的時候就編譯成一個class檔案,在此基礎上做的修改儲存後又會觸發一次編譯。所以我們可以藉助記事本來看看什麼是執行時呼叫,來體驗一下建立物件的兩種方式。
建立字串物件的時候,使用字面值和使用new String()構造器這兩種方式有什麼不同?
當我們使用new String構造器來建立字串的時候,字串的值會在堆中建立,而不會加入JVM的字串池中。相反,使用字面值建立的String物件會被放入堆的PermGen段中。例如: String str=new String(“Test”); 這句程式碼建立的物件s
C++ 類的兩種定義方式
命名 c++ ech += esp set with aced spa 類內定義 class Teacher { private: string _name; int _age; public: Teacher() { printf("create teche
C++調用C代碼的兩種方式
未定義 nbsp fin 代碼 endif log 導致 plus code 由於C++支持函數重載,在編譯函數代碼的時候會加上參數類型的信息,而C編譯只有函數名信息,導致C++直接調用C代碼在鏈接的時候會出現函數未定義的問題。解決這種問題有兩種方法。方法一:在寫C代碼