1、四種對象生存期和做用域ios
棧對象
編程
隱含調用構造函數(程序中沒有顯式調用)安全
堆對象
函數
隱含調用構造函數(程序中沒有顯式調用),要顯式釋放spa
全局對象、靜態全局對象
線程
全局對象的構造先於main函數對象
已初始化的全局變量或靜態全局對象存儲於.data段中ci
未初始化的全局變量或靜態全局對象存儲於.bss段中作用域
靜態局部對象
it
已初始化的靜態局部變量存儲於.data段中
未初始化的靜態局部變量存儲於.bss段中
C++ Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
#include <iostream> using namespace std; class Test { public: Test(int n) : n_(n) { cout << "Test " << n_ << " ..." << endl; } ~Test() { cout << "~Test " << n_ << " ..." << endl; } private: int n_; }; int n; // 未初始化的全局變量,初始值爲0。n存儲於.bss段中。(block started by symbol) int n2 = 100; // 已初始化的全局變量,初始值爲100。n2存儲於.data段中。 Test g(100); // 全局對象的構造先於main函數 static Test g2(200); int main(void) { cout << "Entering main ..." << endl; Test t(10); // 棧上建立的對象,在生存期結束的時候自動釋放 { Test t(20); } { Test *t3 = new Test(30); // 堆上建立的對象,要顯式釋放 delete t3; } { static int n3; // n3存儲於.bss段中 (編譯期初始化) static int n4 = 100; // n4存儲於.data段中 (編譯期初始化) static Test t4(333); // t4對象運行期初始化 .data段 } cout << "Exiting main ..." << endl; } |
2、static 用法總結
1. 用於函數內部修飾變量,即函數內的靜態變量。這種變量的生存期長於該函數,使得函數具備必定的「狀態」。使用靜態變量的函數通常是不可重入的,也不是線程安全的,好比strtok(3)。
2. 用在文件級別(函數體以外),修飾變量或函數,表示該變量或函數只在本文件可見,其餘文件看不到也訪問不到該變量或函數。專業的說法叫「具備internal linkage」(簡言之:不暴露給別的translation unit)。
C語言的這兩種用法很明確,通常也不容易混淆。
因爲C++引入了類,在保持與C語言兼容的同時,static關鍵字又有了兩種新用法:
3.用於修飾類的數據成員,即所謂「靜態成員」。這種數據成員的生存期大於class的對象(實例/instance)。靜態數據成員是每一個class有一份,普通數據成員是每一個instance 有一份。
4. 用於修飾class的成員函數,即所謂「靜態成員函數」。這種成員函數只能訪問靜態成員和其餘靜態成員函數,不能訪問非靜態成員和非靜態成員函數。
參考:
C++ primer 第四版 Effective C++ 3rd C++編程規範