程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> vc教程 >> C++:從棧和堆來理解C#中的值類型和引用類型

C++:從棧和堆來理解C#中的值類型和引用類型

編輯:vc教程

C++中並沒有值類型和引用類型之說,標准變量或者自定義對象的存取默認是沒有區別的。但如果深入地來看,就要了解C++中,管理數據的兩大內存區域:棧和堆。

棧(stack)是類似於一個先進後出的抽屜。它的體積是有限的,一般為2M左右。

而堆(heap)則相對來說體積可以很大,這一般跟計算機的虛擬內存設置有關系。

棧中存取對象的內存是自動回收的,用完即銷毀了,一般方法內部的變量和參數都是通過棧來存取的(但也正因為如此,它們的生命周期很短)。但它的問題是,體積有限。

一些大的對象,我們可能要通過堆來創建它。程序員可以控制這些對象什麼時候創建,什麼時候銷毀。這無疑帶來了靈活性,也同時帶來了一些風險,事實上,相當一部分的程序的崩潰都是因為不恰當地使用了堆,以及沒有及時清理在堆上申請的內存。或者反過來說,可能會清理多次(這也會導致崩潰)。

通常來說,如果希望某個對象或者變量的生命更長一些,也可以將其作為全局變量或者靜態變量。但那樣又導致了它們必須等到程序結束才會釋放。

下面我用一個例子來演示一下這個問題

#include <iostream>
using namespace std;

class human{
public:
    void Talk();
    ~human(){cout<<"析構函數在工作..."<<endl;}
private:
    int age;
};

void human::Talk(){
    cout<<"Hello"<<endl;
}

int main()
{
    human h;//創建一個human對象,這個對象就生存在棧上,它所需的大小是根據其成員決定的
    cout<<"h的大小為:"<<sizeof(h)<<endl;
    cout<<"h的地址是:"<<&h<<endl;
    h.Talk();

    human *p=new human();//通過new關鍵字,是在堆上面創建一個對象,它所申請的空間也是內部成員決定的.這裡也是4
    cout<<"p的大小為:"<<sizeof(p)<<endl;
    cout<<"p的地址為:"<<p<<endl;
    p->Talk();
    delete p;
    //刪除p這個指針指向的堆上面的內存.如果用完該對象,我們不刪除,那麼該內存就一直存在,並不會自動刪除.這就稱為內存洩漏.
    //如果類型定義了析構函數,此時將調用它(反之,如果一個對象是在堆上創建的,那麼除非調用delete語句,否則析構函數不會運行
    cout<<"p的地址為:"<<p<<endl;//我們只是刪除了該塊內存上面的數據,地址還是存在的
    //建議在刪除p之後,將其置為0
    //p=0;
    //delete p;//但如果再次刪除,又會發生崩潰,因為該內存已經沒有了.
    return 0;
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved