2011-10-31 27 views
1

Gotw 80包括下面的例子:gotw 80語法 - 參數列表中初始化

// Example 1 
    // 
    #include <string> 
    using namespace std; 

    class A 
    { 
    public: 
    A(const string& s) { /* ... */ } 
    string f() { return "hello, world"; } 
    }; 

    class B : public A 
    { 
    public: 
    B() : A(s = f()) {} 
    private: 
    string s; 
    }; 

    int main() 
    { 
    B b; 
    } 

文章接着討論爲什麼行s = f()是不正確 - 由於對象生存和施工秩序。文章指出,當時,編譯器沒有找到錯誤。

但是,忽略了初始化順序和對象生存期的問題,我沒有看到構造函數的參數列表中的s = f()如何在語法上合法 - 它似乎試圖在參數列表中初始化成員或者可能聲明一個默認值)。任何人都可以解釋這個語法試圖做什麼?

回答

1

在語法上是合法的......當你有一個構造函數參數的基類,當然你也可以通過任意表達式作爲參數:

strut A { 
    A(int) {} 
}; 

struct B : A { 
    B() : A(any expression that returns an int) {} 
}; 

的問題是,評估該示例中的表達式時該對象甚至還沒有完全構建A實例,以便代碼是兩個不同的原因而無效:

  1. 調用的非實例A的方法(構造函數還不開始):f()通話是非法的。
  2. 分配給尚未初始化的成員:s=...是非法的。
+0

當然..由於某種原因,那天看起來很不尋常 – Taras

3

看起來打算打電話給f()並將結果分配給B::s。之後,調用繼承的A構造函數時,該賦值的結果(即s)將用作實際參數。

它在語法上是有效的。將該表達式中的s替換爲一些非成員變量,g++ accepts it without issue。您可能會看到類似的語法更常用於普通函數調用而不是構造函數調用。