簡體   English   中英

使用placement new來更新引用成員?

[英]Using placement new to update a reference member?

以下代碼在C ++中是否合法?

template<typename T>
class Foo {
public:
    Foo(T& v) : v_(v) {}

private:
    T& v_;
};

int a = 10;
Foo<int> f(a);

void Bar(int& a) {
    new (&f)Foo<int>(a);
}

引用不應該被綁定兩次,對吧?

這完全無效。

[basic.life] / 1,強調我的:

類型T的對象的生命周期在以下情況下結束:

  • 如果T是具有非平凡析構函數(12.4)的類類型,則析構函數調用將啟動,或者
  • 對象占用的存儲器被重用或釋放。

placement new重用存儲,結束f表示的對象的生命周期。

[basic.life] / 7:

如果在對象的生命周期結束之后並且在重用或釋放對象占用的存儲之前,則在原始對象占用的存儲位置創建新對象,指向原始對象的指針,引用引用原始對象,或者原始對象的名稱將自動引用新對象,並且一旦新對象的生命周期開始,就可以用來操縱新對象,如果:

  • 新對象的存儲完全覆蓋原始對象占用的存儲位置,以及
  • 新對象與原始對象的類型相同(忽略頂級cv限定符),和
  • 原始對象的類型不是const限定的,如果是類類型,則不包含任何類型為const限定的非靜態數據成員或引用類型 ,以及
  • 原始對象是類型為T派生程度最高的對象(1.8),新對象是類型為T派生程度最高的對象(也就是說,它們不是基類子對象)。

由於不滿足第三個項目符號點,在調用Barf不會引用由placement new創建的對象,而是引用之前不再存在的對象,並且嘗試使用它會導致未定義的行為。

另見CWG1776P0137R0

這可能是合法的,但它的風格非常糟糕。 放置new的參數是一個void *,所以你告訴C ++將f的地址重新解釋為一個void *,然后用它作為構造新東西的位置 - 覆蓋原始的f。

基本上,不要這樣做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM