繁体   English   中英

派生抽象类中的纯虚方法

[英]Pure virtual methods in derived abstract class

说我们有这个:

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

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

编译器不会抛出错误,我想是因为B也是一个抽象类,因此它不必从A实现foo 。但是这种构造是什么意思呢?

1)是否foo从乙隐藏foo从A?

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。 当一个类至少包含一个纯方法时,它称为abstract 这是什么意思? 这意味着该类无法实例化,因为它需要纯方法实现。

您显然可以从抽象类继承(我想您被迫这样做,否则,除了提供从其继承的接口之外,您将不需要使用一个抽象类)?从抽象类继承而未实现父类的部分或全部纯方法; 在这种情况下,子类也是抽象的,就像您的B类一样:

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

在B中,您可以轻松省略virtual void foo() = 0; 声明,因为该定义已从基类继承。 在这种情况下,类B是抽象类,因此无法像A一样实例化。

要更直接地回答您的问题:

请问foo的B隐藏foo从A?

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

第一个继承自B的类不是抽象类,是否必须提供两个提供的实现,如提供的一个?

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

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

0)编译器没有抛出错误...

当您尝试从抽象的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基类的功能。 如果通过指针或对基类的引用来调用它,则会调用派生类中的函数。 它“覆盖”基类中的那个。 仅当您通过指针或引用或直接与派生类的对象调用非虚函数时, 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;
      }
 };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM