[英]C++: when object constructed in argument is destructed?
當在參數中構造的對象被破壞時,在函數調用之前還是之后?
例如,以下代碼安全嗎?
void f(const char*)
{ ... }
std::string g()
{ ... }
...
f(g().c_str());
它始終對我有用,但我不知道它只是未定義的行為還是實際上應該起作用。
它始終對我有用,但我不知道它只是未定義的行為還是實際上應該起作用。
不,沒有未定義的行為,因為由g()生成的臨時對象將在評估完整表達式(即f()函數的主體)后刪除。
C ++標准n3337§12.3 / 3
當實現引入具有非平凡構造函數的類的臨時對象(12.1、12.8)時,應確保為該臨時對象調用構造函數。 同樣,析構函數應被調用為具有非平凡析構函數的臨時變量(12.4)。 臨時對象被銷毀,是評估(按詞法)包含創建它們的點的完整表達式(1.9)的最后一步。 即使該評估以引發異常結束也是如此。 破壞的價值計算和副作用
C ++標准n3337§12.3 / 4
在兩種情況下,臨時變量在與完整表達式末尾不同的位置被銷毀。 第一個上下文是調用默認構造函數初始化數組的元素時。 如果構造函數具有一個或多個默認參數,則在構造下一個數組元素(如果有)之前,將對在默認參數中創建的每個臨時變量的銷毀順序進行排序。
C ++標准n3337§12.3 / 5
第二種情況是引用綁定到臨時項時。 (...)
g()
是臨時的。 臨時變量的生命周期會在整個完整表達式的評估過程中持續(在您的情況下,將為f(g().c_str())
)因此,除非f()
將指針存儲在某個地方,否則您的用法是安全的。
§12.2/ 4在兩種情況下,臨時變量在與全表達式末尾不同的位置被銷毀。 第一個上下文是表達式作為定義對象的聲明程序的初始化程序出現時。 在這種情況下,保存表達式結果的臨時對象將一直保留,直到對象的初始化完成為止。 [...]
§12.2/ 5第二種情況是引用綁定到臨時項時。 [...]
這兩種情況均不適用於您的示例。
評估包含表達式的完整表達式后,將分解為表達式評估一部分的臨時對象,除非將其綁定到命名引用。 (當前標准草案中的12.2和1.9是相關章節)。
因此,在您的示例中,構造為保存g
的返回值的臨時對象將在f
返回之后被銷毀。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.