公共继承是否允许重写基类成员访问器

Does public inheritance allow to override the base classes member accessors?

本文关键字:重写 基类 成员 访问 继承 是否 许重写      更新时间:2023-10-16

我在一个代码示例中看到一些奇怪的东西。有一个基类和一个派生类。派生类从具有公共继承的基类派生而来。

class baseClass
{
public:
    void foo();
}
class derivedClass : public baseClass
{
protected:
    void foo();
}

派生类还覆盖了方法foo()的访问器。foo()baseClass中的public, derivedClass中的protected。它可以构建和工作,但我不明白为什么有人会这样做,也不知道这在多大程度上是允许的。例如,protected缩小了访问范围,所以它是允许的,但是你不能用public?我不知道。

你写的东西有点棘手。代码的结果不会是您所期望的。如果你创建并使用derivedClass实例你就不能调用foo(),因为它是受保护的:

derivedClass object;
object.foo(); // Compilation error. Cannot access.

但是如果你创建一个指向derivedClass类对象的指针并调用foo()函数,它将调用baseClassfoo()而不是derivedClassfoo(),因为它不是基类中的虚函数。

baseClass* object = new derivedClass;
object->foo(); // This will call baseClass::foo();

隐藏函数时就是这种情况。如果将virtual关键字添加到foo(),则将调用derivedClassfoo()

class baseClass
{
public:
    virtual void foo();
}
class derivedClass : public baseClass
{
protected:
    virtual void foo() override;
}

用法:

baseClass* object = new derivedClass;
object->foo(); // This will call derivedClass::foo();

虚函数可以被重写。这是虚函数的一个点。

但是,在您的示例中,derivedClass::foo()隐藏了baseClass::foo()。它不会覆盖它。

//  your class definitions here
int main()
{
     baseClass b;
     derivedClass c;
     baseClass *pb = &b;
     baseClass *pc = &c;
     b.foo();     // will call baseClass::foo()
     pb->foo();   // will also call baseClass::foo()
     pc->foo();   // will also call baseClass::foo()  (not derivedClass::foo() which would be the case if baseClass::foo() was virtual)
     c.foo();     //  will attempt to call derivedClass::foo(), which the compiler will reject since it is protected                      
}

语句c.foo()将编译如果derivedClass::foo()public,并将调用derivedClass::foo()。根据编译器和编译器的设置,编译器可能会发出baseClass::foo()被隐藏的警告。