2014-10-30 148 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因此,在这种情况下,总是给正如你所期望的那样。

相关问题