派生抽象类中的纯虚方法

Pure virtual methods in derived abstract class

本文关键字:方法 抽象类 派生      更新时间:2023-10-16

假设我们有这个:

class A
{
   public:
   virtual void foo() = 0;
};
class B: public A
{
   public:
   virtual void foo() = 0;
};

编译器抛出没有错误,我猜这是因为B也是一个抽象类,因此它不需要从A实现foo。但是这样的构造意味着什么呢?

1) B的foo隐藏了A的foo ?

2)从B继承的第一个类不是抽象类,它是否必须提供两个实现,如:
class C: public B
{
   public:
   virtual void A::foo() {};
   virtual void B::foo() {};
};

如果缺少B::foo()的实现,编译器只会报错,但是不会报错A::foo()

总而言之:这是一种隐藏纯虚拟方法的方法吗?

当你第一次声明:

class A
{
   public:
   virtual void foo() = 0;
};

你正在声明foo方法public, virtual和pure。当一个类至少包含一个纯方法时,它被称为抽象。这是什么意思?这意味着类不能被实例化,因为它需要纯方法实现。

你显然可以从一个抽象类继承(我想说你是被迫这样做的,否则你不需要一个抽象类,除了提供一个接口来继承吗?)你也可以从一个抽象类继承,而不实现父类的一些或全部纯方法;在这种情况下,子类也是抽象的,这是你的类B的情况:

class B: public A
{
   public:
   virtual void foo() = 0;
};
在B中,您可以很容易地省略virtual void foo() = 0;声明,因为该定义已经从基类继承。在这种情况下,类B是一个抽象类,因此不能像a一样被实例化。

更直接地回答你的问题:

foo from B hide foo from A?

不,它没有。它们都声明了一个纯方法(实际上是同一个方法),因此没有什么真正的隐藏

从B继承的第一个类不是抽象类,它是否必须像提供的那样提供两个实现?

不,当然不是。如上所述,它们是相同的方法,因此,如果类C必须为foo提供实现,它应该只实现foo:

class C: public B
{
   public:
   virtual void foo() {};
};

当你尝试实例化AB中的抽象对象时,它将抛出错误。当你继承和声明它们的时候就不会。

,

1) B中的foo隐藏了A中的foo吗?

。它会覆盖A::foo而不是隐藏它

,

2)第一个继承自B且不是抽象类的类;它必须提供两个实现吗?

。只需覆盖foo,并为它做一个实现。

,

class C : public B
{
public:
    virtual void foo()
    {
        std::cout << "ABCD" << std::endl;
    }
};

int main()
{
    C c;
    A *a = &c;
    a->foo(); //  Prints ABCD string and proofs B::foo doesn't hide A::foo
}

我用gcc 4.5.3编译了你的代码,它给出了以下错误消息:

error: cannot define member function ‘A::foo’ within ‘C’
error: cannot define member function 'B::foo' within 'C'

在你的例子中,类AB都是抽象类,因为foo是纯虚的。它们只定义B的派生类应该实现foo的行为,因为没有默认行为可使用(如果派生类不再是抽象的)。

Question 1:Does foo from B hide foo from A?

由于BA中的foo具有完全相同的名称,相同的签名并且foo在基类中是虚拟的,所以它不是隐藏的,它是重写的。仅供参考:如果签名相同并且在基类中声明为虚函数,则派生类的函数overrides是基类函数。如果你称之为类中的函数通过指向基类的指针或引用派生类被调用。它"覆盖"基类中的那个。只有在通过a调用非虚函数时才会使用Hiding指针或引用,或直接指向派生类的对象。一个派生类的函数隐藏所有同名的基类函数。

Question 2: The first class which inherits from B and is not an abstract class, does it have to provide two implementations

。您可以执行以下操作:

  class C: public B
  {
   public:
      virtual void foo()
      {
        cout << "foo defined in c" <<endl;
      }
 };