2009-08-20 48 views
1

爲什麼我不能在B類初始化列表中訪問基類A的成員?從C++中導出問題

class A 
    { 
    public: 
     explicit A(int a1):a(a1) 
     { 
     } 
     explicit A() 
     { 
     } 

    public: 
     int a; 

    public: 
     virtual int GetA() 
     { 
      return a; 
     } 
    }; 

    class B : public A 
    { 
    public: 
     explicit B(int a1):a(a1) // wrong!, I have to write a = a1 in {}. or use A(a1) 
     { 
     } 
     int GetA() 
     { 
      return a+1; 
     } 
    }; 

    class C : public A 
    { 
    public: 
     explicit C(int a1):a(a1) 
     { 
     } 
     int GetA() 
     { 
      return a-1; 
     } 
    }; 
+0

我已經改變了措辭,使問題更加具體:您不能從初始化列表中訪問字段,而您確實可以從構造函數體中訪問它。 – 2009-08-21 06:40:16

回答

6

A的構造函數之前B的運行,並且,或明或暗地,前者構造A的所有實例,其中包括a成員。因此B不能在a上使用構造函數,因爲該字段已經構建。你試圖使用的表示法正好表示要在a上使用構造函數,並且在那一點上它是不可能的。

6

要建立在亞歷克斯通過控制其建設的回答,您可以初始化基類的‘一’成員,像這樣:

class B : public A 
{ 
public: 
    explicit B(int a1) : A(a1) { } // This initializes your inherited "a" 
    ... 
}; 

請注意,我構建的基類(資本「A」),而不是嘗試直接初始化其繼承成員(小寫「a」,從您的示例中繪製)。

+0

非常感謝,pilcrow :) – user25749 2009-08-20 08:39:48

0

爲了進一步鞏固段落符號的答案,你可以很容易地通過在B級覆蓋它初始化是你想要的成員:

class B : public A 
{ 
public: 
    int a; // override a 

    explicit B(int a1) : a(a1) // works now 
    { 
    } 

    ... 
}; 

雖然,我不一定會推薦這一點;)

+0

哈!新徽章:「巴別塔」,用於延伸本身已經擴展的答案。 :) – pilcrow 2009-08-20 04:47:58