2016-04-23 121 views
-1

我有一個基類,從該基類派生的類,以及從派生類派生的另一個類。我的問題來自於使用構造函數來確定如何構建下一個類。C++繼承和類成員

這裏是使用繼承時遇到的問題的簡化版本。我是新來的C++。

基類:

class Grandfather 
{ 
    public: 
     Grandfather(int A, int B, int C) : a(A), b(B), c(C) 
     {} 

     virtual ~Grandfather(); 
     virtual int getA(); 
     virtual int getB(); 
     virtual int getC(); 

    private: 
     int a,b,c; 

}; 

派生父類:

class Father : public Grandfather 
{ 
    public: 
     Father(int d); 
     virtual ~Father(); 
    private: 
     int c; // i know this at compile time. How to define? 

}; 

其中Father.cpp,構造的定義如下:

Father::Father(int d){ 
    int a,b; //Father takes a parameter that then determines what a and b are 

    switch(d){ 
     case 1: 
      a=2; 
      b=5 
     case 2: 
      a=6; 
      b=9; 
     default: 
      a=10; 
      b=2; 
    } 


    Grandfather(a,b,c); // where c is a known constant for this class 
} 

和派生,派生子類:

class Child : public Father 
{ 
    public: 
     Child() : Father(int d) // d is a known constant for this class 
     {} 
     virtual ~Child(); 
    private: 
     int d; // how do i define d, if it is known at compile time? 

}; 

因此,Child在編譯時具有已知的整數值。當創建一個Child對象時,它會自動調用帶有其變量的構造函數Father。構造函數Father(in d)查看從Child傳入的變量,進行快速操作,然後調用已知的int c的GrandFather構造函數和根據給出的int d創建的另外兩個int a,b。這顯然是不行的,因爲默認Grandfather()構造函數自動調用

+2

'enum {d = X};'在代碼註釋中回答您的問題。 – kfsone

+0

相反,模板參數,可選'靜態constexpr int'成員。如果OP想用傳遞給構造函數的參數初始化它,太糟糕了,只能是'const int'。 – LogicStuff

+0

修正'Child'構造函數中的錯別字。 – LogicStuff

回答

1

這顯然是行不通的,因爲默認的祖父()構造函數會被自動調用

良好的漁獲物,並Grandfather(a,b,c);創建一個單獨的臨時實例。

你可以做什麼:

Father::Father(int d) : 
Grandfather(determine_a(d), determine_b(d), c) // c is static constexpr 
{ 
} 

這可能是兩個功能,或者您也可以使用std::array和一個determine_ab功能重構它。這是你的選擇。

+0

不錯,這些確定函數可以成爲父類的成員嗎? –

+1

他們可能是非會員或「父親」的「私人」「靜態」或「祖父」的「受保護」靜態功能。 – LogicStuff

1

如果您不需要Father類中的int c值,並且您在編譯時知道它,只需在對Grandfather的構造函數的調用中對其進行硬編碼即可。與Child類中的int d值相同。要在調用Grandfather的構造函數之前確定AB的值,我認爲LogicStuff具有正確和最漂亮的答案。我給你寫了一個簡短的例子,我簡化了原始代碼,並且使用了TS代碼中最相關的部分。隨意添加其餘的。

class Grandfather 
{ 
     public: 
       Grandfather (int A, int B, int C) : a (A), b (B), c (C) { } 
     private: 
       int a, b, c; 
}; 

class Father : public Grandfather 
{ 
     public: 
       Father (const int d) : Grandfather (determine_a (d), determine_b (d), 4) { } 
       int determine_a (const int); 
       int determine_b (const int); 
}; 

class Child : public Father 
{ 
     public: 
       Child () : Father (3) { } 
}; 

int Father::determine_a (const int d) 
{ 
     if  (d == 1)  { return 2; } 
     else if (d == 2)  { return 6; } 
     else     { return 10; } 
} 

int Father::determine_b (const int d) 
{ 
     if  (d == 1)  { return 5; } 
     else if (d == 2)  { return 9; } 
     else     { return 2; } 
} 
+0

謝謝你的重寫。此外,你格式化這些if語句的方式看起來很漂亮!比方說,在編譯時,我們有一個已知的對象,而不是在編譯時已知的int。我能否在沒有錯誤的情況下硬編碼對象在祖父的構造函數中的實例化? –

+1

自從我上次寫C++以來已經有六個月了,所以我有點生疏了。但我已經糾正了我的例子中的錯誤。我不太清楚你在問什麼,但是你不能硬編碼一個對象的實例。您需要該對象的地址,並且在編寫代碼時不知道該對象的地址。 – BufferOverflow