11

假设我们有这个:

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

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

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

1) B 是否foo对 A 隐藏foo

2)从B继承的第一个类不是抽象类,它是否必须提供两个实现,例如:

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

编译器仅在B::foo()缺少 的实现时才会抱怨,但不会抱怨缺少A::foo().

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

4

3 回答 3

14

当您第一次声明时:

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

您将方法声明为foopublic、virtual 和 pure。当一个类至少包含一个纯方法时,它被称为abstract。这是什么意思?这意味着该类无法实例化,因为它需要纯方法实现。

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

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

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

更直接地回答您的问题:

foo从B隐藏fooA ?

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

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

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

class C: public B
{
   public:
   virtual void foo() {};
};
于 2013-03-24T21:00:24.307 回答
8

0) 编译器不会抛出错误...

A当您尝试实例化对象或B它们是抽象的对象时,它将引发错误。不是在您继承和声明它们时。

 

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
}
于 2013-03-24T20:29:13.183 回答
1

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

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

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

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

由于fooinBA具有完全相同的名称,相同的签名和 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;
      }
 };
于 2013-03-24T20:53:23.447 回答