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

Posted

技术标签:

【中文标题】如何在C++中继承后覆盖基类的成员【英文标题】:How to override member of base class after inheritance in C++ 【发布时间】:2009-07-14 07:33:53 【问题描述】:

我有这个:

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 
        

【问题讨论】:

【参考方案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;
        

【讨论】:

当我尝试您的第一个示例时,我得到 B:非法成员初始化:'m_PA' 不是基础或成员 这就是为什么你在 private 下写 m_Pa。如果私有成员不是基类,则不能更改它。您只能更改派生类的受保护或公共成员。也可能你在 m_Pa(new Foo(*this)) 之前写了“:”而不是“,”【参考方案2】:

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

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


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

【讨论】:

【参考方案3】:

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

【讨论】:

【参考方案4】:

简短回答:通过声明 m_Pa 私有,您是说只有 class A 应该能够修改它。所以你不能使用class B的方法改变它的值。

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

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

Foo* getPa() 
  return m_Pa;


void setPa(Foo* Pa) 
  m_Pa = Pa;

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

关于术语的注释:在 C++ 中“覆盖”成员通常是指提供virtual 成员函数的新实现。所以如果你的class A 有一个方法

virtual void doIt()

那么class B 中相同类型的成员会覆盖AdoIt() 的实现。

【讨论】:

以上是关于如何在C++中继承后覆盖基类的成员的主要内容,如果未能解决你的问题,请参考以下文章

c++继承是如何工作的?

C++中继承与多态

如何实现基类的虚方法,并在c#中的覆盖方法中获取基方法实现[重复]

C++中如何在子类的构造函数中调用基类的构造函数来初始化基类成员变量

在 C++ 中将指向基类的指针传递给派生类的成员函数

如何在 JavaScript 中继承 C++ 类?