如何在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++(和大多数其他面向对象的编程语言)中,您不仅要声明成员的类型,还要声明其可见性(public
、protected
和 private
)。这允许你封装数据:你只公开一个接口,但你不能让你的类的客户直接修改它的内部。
在您的具体示例中,我将创建访问器
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
中相同类型的成员会覆盖A
的doIt()
的实现。
【讨论】:
以上是关于如何在C++中继承后覆盖基类的成员的主要内容,如果未能解决你的问题,请参考以下文章
如何实现基类的虚方法,并在c#中的覆盖方法中获取基方法实现[重复]