物件或參考的壽命是物件或參考的一個運行時屬性。如果一個變數是默認初始化的,并且如果它是型別別或其(可能是多維)陣列,該型別別有一個瑣碎的默認建構式,那么該變數就被稱為具有空閑初始化。型別為
T的物件的生命周期從以下時間開始:
- 獲得具有
T型別的適當對齊和大小的存盤,并且- 它的初始化(如果有的話)已經完成(包括空洞的初始化)([dcl.init]),
。但如果該物件是一個聯合體成員或其子物件,那么只有當該聯合體成員是聯合體中的初始化成員([dcl.init.aggr], [class.base.init]),或者如 [class.union] 和 [class.copy.ctor] 中所述,以及如 [allocator.members] 中所述,其壽命才開始。
如果沒有為一個物件指定初始化器,那么這個物件就是默認初始化的。
當獲得具有自動或動態存盤期限的物件的存盤時,該物件具有一個不確定的值,如果沒有對該物件進行初始化,該物件將保留一個不確定的值,直到該值被替換([expr.ass])。 [注1。具有靜態或執行緒存盤期限的物件是零初始化的,見 [basic.start.static]。- 結束注釋]
考慮一下這個C 程式:
int main(){
int i;
i = 3;
return 0;
根據C 標準,初始化是在函式main的第一條陳述句int i;還是第二條陳述句i = 3;進行的?
我認為是前者,它對一個不確定的值進行了空洞的初始化,因此開始了物件的生命周期(后者不執行初始化,它執行了對值3的分配)。如果是這樣的話,真的有可能將存盤分配與物件初始化分開嗎?
uj5u.com熱心網友回復:
如果是這樣的話,真的有可能將存盤分配與物件初始化分開嗎?
是的:
void *ptr = malloc(sizeof(int) )。)
ptr指向分配的存盤空間,但是沒有物件生活在該存盤空間中(C 20說有些物件may在那里,但是現在不要管它)。除非我們在那里創建一些物件,否則物件將不會存在:
new(ptr) int;
uj5u.com熱心網友回復:
你正在混淆為一個物件分配存盤空間和初始化一個物件,它們絕對是不是同一件事。
在你的例子中,物件i從未被初始化。作為一個本地值,它有保留的空間用于存盤,但是它沒有被初始化任何值。
第二行的陳述句給它分配了一個3的值。這也不是初始化。
具有全域存盤的物件,其數值為3。
標準要求具有全域存盤的物件既要被分配又要被初始化(初始化為零或默認初始化器所做的任何事情)。所有其他物件只有在書面語言結構能夠支持的情況下才被初始化。
C 分配器的作業原理也是如此。new運算子在幕后既分配又初始化物件,之后您可以為物件分配一個新的值。不過,如果您需要,您可以使用底層語言構造來分別管理這兩件事。
在大多數情況下,您不需要在代碼中關心物件初始化和賦值之間的區別。如果你到了需要關注的地步,你要么已經知道這兩個概念的區別,要么需要快速學習。
uj5u.com熱心網友回復:
根據C 標準,是在函式
main的第一條陳述句int i;還是第二條陳述句i = 3;中進行初始化?
第一條。第二條陳述句是賦值,不是初始化。第二條陳述句標志著 "直到該值被替換([expr.ass])"這一點來自你對標準的參考。
如果[初始化是第一條陳述句]是這樣的話,那么真的有可能將存盤分配與物件初始化分開嗎?
是的,但在你這樣一個簡單的例子中并不是這樣。我想到的一個常見的例子是std::vector。保留容量分配了存盤空間,但是在向量中添加物件之前,該存盤空間不會被初始化。
std::vector<int> v; // Allocates and initialize the vector object.
v.reserve(1); //確保空間已經被分配給int物件。
/*
在這一點上,第一個包含的元素已經分配了空間,但還沒有被初始化。
還沒有被初始化。如果你想在分配和物件初始化之間做一些瘋狂的事情
和物件初始化之間做一些瘋狂的事情,這里就是做這些事情的地方。請注意,你不能
不允許訪問分配的空間,因為它屬于向量。
你必須復制一個向量的內部作業機制來做這件事......
*/
v.emplace_back(3); // Initializes the first contained object.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/306742.html
標籤:
