2014-03-27 65 views
1

我有以下簡單的代碼:對象之前使用對象成員構造

#include <iostream> 
#include <vector> 

template <class Derived> 
struct Base 
{ 
    Base() 
    { 
     static_cast<Derived*>(this)->foo(); 
    } 

    std::vector<int> m_ints; 
}; 

struct Derived : Base<Derived> 
{ 
    Derived() : Base() 
    { 
     std::cout << a; 
    } 

    void foo() 
    { 
     m_ints.push_back(37); 
     a = 4; 
    } 

    int a; 
}; 

int main() 
{ 
    Derived d; 
    return 0; 
} 

我瞭解創建對象時調用構造函數的順序。構造函數從「最基礎 - >向下」調用。所以在Base構造函數中Derived對象沒有完全構造。

1)它是安全的,叫Derived::fooBase構造,當Derived::foo做沒有觸摸Derived對象?我的意思是,當沒有像a = 4這樣的行時,只需觸碰Base對象。

2)如果我運行代碼發佈,它確實有效,雖然我碰a不應該在那個時候存在。它保證工作嗎? (我測試VS2013,VS2010和GCC 4.8.1 on Ideone

+0

你想做什麼? – BlackMamba

+0

看看[這個](http://stackoverflow.com/a/23417203/2567683) –

回答

0

它會在這個特定的情況下工作,但我會建議不要這樣做。 代碼中的細微變化可能會突然中斷邏輯(例如,某人使foo虛擬方法,某人在構造函數中初始化數據成員a或Derived,...)。

如果基類需要來自派生類的信息,那麼派生類必須將該信息傳遞給基類的構造函數。在這個類中,值37應該從Derived的構造函數傳遞給Base的構造函數。

而且當數據成員a必須初始化時,在Derived的構造函數中初始化它,而不是在其他地方初始化它。

編輯:在C++ 11中,如果Derived類想要在Base的構造函數中注入代碼,它可以將lambda傳遞給Base。 Base然後只是在它的構造函數中執行lambda。

+0

謝謝你的回答。你能否提供更多的信息如何從Derive do Base傳入lambda以便能夠在Base構造函數中調用lambda?在實際情況下,Derive有幾個構造函數,我不想在每個構造函數中傳遞lambda。有另一種方法嗎? – relaxxx