1. 程式人生 > >C++建立物件的兩種方式

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 namespace
std; 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'; ****************************************

CC語言前序建立二叉樹的方式和前序遍歷二叉樹的方法

#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代碼