如何在C ++中继承后覆盖基类的成员

时间:2009-07-14 07:33:53

标签: c++ inheritance constructor

我有这个:

class A {
    public :
        A(int i ) : m_S(i)
        {  
            m_Pa = new Foo(*this) ;
        }
    private :
        int m_S ;
        Foo* m_Pa;
}

and derived class 

class B : public A {
    public :
        B() : A (242) 
        {
          // here i like to override the A class m_Pa member but i don't know how to do it right 
        }
}

4 个答案:

答案 0 :(得分:1)

什么是m_Pa?你从未宣布它。假设它是A类中Foo *类型的私有数据成员,除非更改A的接口,否则不能在派生类中直接更改它。例如,您可以提供受保护的setter成员函数:

class A {
....
protected:
 void setFoo(const Foo* foo);
}

class B {
 ....
 Foo *foo = new Foo(this);
 setFoo(foo);
}

答案 1 :(得分:1)

你的m_Pa应该受到保护,而不是你可以调用:

 B() : A (242), m_Pa(12) 
 {

 }

 B() : A (242)
 {
   m_PA = 55
 }

或者您应该创建一个更改m_Pa

的公共或受保护函数
 class A {
     public :
         A(int i ) : m_S(i)
         {  
              m_Pa = new Foo(*this) ;
         }

        void setPA(int val)
        {
             m_PA = val;
        }

答案 2 :(得分:0)

您不能覆盖派生类中的成员变量,只能覆盖方法。

答案 3 :(得分:0)

简短回答:通过声明m_Pa私有,您说只有class A才能修改它。因此,您无法使用class B

的方法更改其值

更长的答案:在C ++(以及大多数其他面向对象的编程语言)中,您不仅要声明成员的类型,还要声明其可见性(publicprotectedprivate )。这允许您对数据进行封装:您只公开一个接口,但不允许您的类的客户端直接修改其内部。

在您的具体示例中,我将创建访问者

Foo* getPa() {
  return m_Pa;
}

void setPa(Foo* Pa) {
  m_Pa = Pa;
}
<{1>}中的

并在class A中使用它们来修改class B。如果您希望m_Pa(但不是无关的类)能够修改class B在您班级的m_Pa部分中声明getPa()setPa();如果您希望任何客户修改它们,请在protected:部分声明它们。特别是在后一种情况下,您需要开始担心对象所有权,即哪个对象负责删除存储在构造函数中创建的public:中的对象。这个问题的实际解决方案是使用智能指针,例如参见boost's implementation

关于术语的说明:“覆盖”C ++中的成员通常是指给出m_Pa成员函数的新实现。因此,如果您的virtual有方法

class A

然后virtual void doIt() 中相同类型的成员会覆盖class B的{​​{1}}的实现。