2014-10-30 142 views
0

下面是我想要做的一個例子。基本上我的GetInt()函數是在基類A中定義的,而我的派生類B也應該使用相同的定義。但問題是,當我從類B的對象訪問GetInt()時,我想返回派生類的成員而不是基類的成員。但是,下面的代碼的輸出提供:訪問派生類成員的基類函數

Constructor A called 
Constructor A called 
Constructor B called 
Object A: 10 
Object B: 10 

,而我希望它是:

Constructor A called 
Constructor A called 
Constructor B called 
Object A: 10 
Object B: 5 


class A{ 
     public: 
       A(){ 
         std::cout << "Constructor A called" << std::endl; 
         m_nA = 10; 
       } 
       int GetInt(){ 
         return m_nA; 
       } 
     private: 
       int m_nA; 
}; 
class B : public A{ 
     public: 
       B(){ 
         std::cout << "Constructor B called" << std::endl; 
         m_nA = 5; 
       } 
     private: 
       int m_nA; 
}; 

int main(){ 
     A ObjA; B ObjB; 
     std::cout << "Object A: " << ObjA.A::GetInt() << std::endl; 
     std::cout << "Object B: " << ObjB.B::GetInt() << std::endl; 
     return 0; 
} 

請建議,如果有任何的方式來做到這一點。由於

回答

2
private: 
      int m_nA; 

變化的基類「A」以上爲「受保護」。 不要在「B類」中定義成員「m_nA」。 那就是它!你已準備好出發。

0

你需要讓GetInt()虛擬和在子類中重寫它:

class A{ 
    public: 
     A(){ 
      std::cout << "Constructor A called" << std::endl; 
      m_nA = 10; 
     } 

     virtual int GetInt(){ 
      return m_nA; 
     } 

    private: 
     int m_nA; 
}; 

class B : public A{ 
    public: 
     B(){ 
      std::cout << "Constructor B called" << std::endl; 
      m_nA = 5; 
     } 

     virtual int GetInt(){ 
      return m_nA; 
     } 

    private: 
     int m_nA; 
}; 
Constructor A called 
Constructor A called 
Constructor B called 
Object A: 10 
Object B: 5 

既然你明確指定類型A::B::調用該方法,你不一定需要使其虛擬 - 但您無法通過指針或參考A(無後期綁定)呼叫B::GetInt()

A& ObjAb = ObjB; 
std::cout << "Object B through A&: " << ObjAb.GetInt() << std::endl; 

使用虛擬方法:

Object B through A&: 5 

對於非虛方法:

Object B through A&: 10 
+0

無需再聲明GetInt在B類中是虛擬的,一旦在基類中虛擬化,其子類中的函數可覆蓋 – 2014-10-30 08:51:16

+0

@DebasishJana true,但我更願意在子類中重複它,以使其可見一個虛擬的方法。特別是,'虛擬'根本就不是必需的,因爲OP不會通過指針或引用來調用它。 – 2014-10-30 08:52:54

+1

如果他打算只使用它,它甚至不需要在基類中是虛擬的。 – JorenHeit 2014-10-30 08:52:59

1

要調用A::GetInt(),而且總是返回A::m_nA

除非你可以改變的B::m_nA名稱,你可以做的唯一的事情使用虛擬功能:

class A{ 
     public: 
       A() : m_nA(10){ 
         std::cout << "Constructor A called" << std::endl; 
       } 
       virtual int GetInt(){ 
         return m_nA; 
       } 
     private: 
       int m_nA; 
}; 
class B : public A{ 
     public: 
       B() : A(), m_nA(5){ 
         std::cout << "Constructor B called" << std::endl; 
       } 
       virtual int GetInt(){ 
         return m_nA; 
       } 
     private: 
       int m_nA; 
}; 
1

虛擬功能是一個不錯的選擇,但您也可以使用此代碼。

class A{ 
public: 
    A(){ 
     std::cout << "Constructor A called" << std::endl; 
     m_nA = 10; 
    } 

    int GetInt(){ 
     return m_nA; 
    } 

protected: 
    int m_nA; 
}; 

class B : public A{ 
public: 
    B(){ 
     std::cout << "Constructor B called" << std::endl; 
     m_nA = 5; 
    } 
}; 

在這種情況下,當我們所說的B類構造函數它首先調用類構造函數所以用10初始化m_nA的如果是B類構造的身體它覆蓋m_nA的值與5因此,在這種情況下,總是給正如你所期望的那樣。

相關問題