2015-05-20 60 views
10

假設我想調用我的對象的外部函數來在正文構造函數中執行一些檢查。由於構造函數的主體完成執行時對象的生命週期開始,它是不安全的設計嗎?C++:對象的生命週期和外部函數

struct A; 

void check(A const&) { /* */ } 

struct A 
{ 
    A() { check(*this); } 
}; 

我的意思是,我打電話和外部功能與尚未活着的對象。它是不確定的行爲?相關問題:如果我把這個檢查函數作爲一個成員函數(靜態或非靜態),那麼標準中有關在構造函數外但在類內部使用非活動對象的說法是什麼?

它在一個類和它的用戶的觀點(一種在課堂上還是在課外生活時間)之間的生命期概念上有任何不同?

+2

[C++ FAQ](https://isocpp.org/wiki/faq/ctors#using-this-inctors)有關於此的信息。 –

+0

只要該函數不是虛擬成員並且不在初始化列表中,它應該沒問題 – KABoissonneault

+1

const&是一個引用,在檢查開始時既不初始化,也不在函數結束時銷燬。除了構造函數內部的對象完全構造。我在這個代碼中看不到任何問題 – Brahim

回答

8

A壽命會因爲,從[base.life]不用時check()被稱爲開始:

T類型的對象的生存期開始時:

  • 存儲與如果對象具有非真空初始化,則其初始化完成,則獲得T類型的適當對齊和尺寸,並且獲得

A具有非真空初始化。其初始化完成時,從[class.base.init]/13:

在非委託構造,初始化進行以下順序:

  • ...
  • - 最後,執行構造函數體的複合語句

然而,儘管不A具有其壽命開始然而,標準的另外提供,在[class.base.init]/16:

成員函數(包括虛擬成員函數,10.3 )可以針對正在構建的對象進行調用...但是,如果這些操作是在所有存儲器之前在ctor初始化器(或者直接調用 或間接地從ctor初始化器) initi對於基類已經完成的修改器,操作的結果是未定義的。

至於一生的問題,有沒有什麼區別:

void check(const A&) { .. } 
struct A { 
    A() { check(*this); } 
}; 

和:

struct A { 
    void check() const { .. } 
    A() { check(); } 
}; 

後者明確地允許(因爲它不是在一個構造函數初始化程序 ),所以我認爲沒有理由在終生的理由中排除前者。

+0

...除非A是一個虛擬成員的基類,它被'check()'調用 - 那麼結果可能會讓你感到驚訝。 –

+0

@RichardHodges雖然它不是未定義的行爲。 – Barry

+0

@Barry你確定初始化結束嗎? http://stackoverflow.com/a/20409911/1794803 –