Pure virtual methods in derived abstract class

12,520

Solution 1

When you first declare:

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

you are declaring the method foo public, virtual and pure. When a class contains at least a pure method it's called abstract. What does it mean? It means that the class cannot be instantiated because it needs the pure methods implementations.

You can obviously inherit from an abstract class (I'd say that you are forced to do that, otherwise what would be the need of an abstract class you are not using, except for providing an interface to inherit from?) and you can also inherit from an abstract class and not implement some or all of the pure methods of the parent class; in this case the child class is abstract as well, which is the case of your class B:

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

In B you could easily omit the virtual void foo() = 0; declaration because the definition is already inherited from the base class. In this case class B is an abstract class and therefore cannot be instantiated, just like A.

To answer your questions more directly:

Does foo from B hide foo from A?

No, it does not. They both are declaring a pure method (which is in fact the same method), therefore there's nothing to really hide.

The first class which inherits from B and is not an abstract class, does it have to provide two implementations like the one provided?

No, of course not. As stated above, they are the same method, therefore if class C have to provide an implementation for foo it should just implement foo:

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

Solution 2

0) The compiler throws no error ...

It will throw an error when you try to instantiate an object from A or B which they're abstract. Not when you're inheriting and declaring them.

 

1) Does foo from B hide foo from A?

No. It overtides A::foo not hides it.

 

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

No. Just override foo and make one implementation for it.

 

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
}

Solution 3

I compiled your code with gcc 4.5.3, it gave the following error messages:

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

In you example, both class A and B are abstract classes since foo is pure virtual. They only define that derived class of B should implement the behavior of foo since there is no default behavior to use (if the derived class is not abstract anymore).

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

Since foo in B and A has exactly the same name, same signature and foo is virtual in base class, so it is not hiding, it is overriding. FYI: A derived class's function overrides a base class function if the signature is the same and it's declared virtual in the base class. If you call it through a pointer or a reference to the base class, the function in the derived class is called. It "overrides" the one in the base class. Hiding only comes into play if you call a non-virtual function through a pointer or reference or directly with an object of the derived class. A derived class' function hides all base class functions with the same name.

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

No. You can do the following:

  class C: public B
  {
   public:
      virtual void foo()
      {
        cout << "foo defined in c" <<endl;
      }
 };
Share:
12,520
Juergen
Author by

Juergen

Updated on June 05, 2022

Comments

  • Juergen
    Juergen almost 2 years

    Say we have this:

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

    The compiler throws no error, I guess its because B is also an abstract class and as such it does not have to implement foo from A. But what does such a construct mean?

    1) Does foo from B hide foo from A?

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

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

    The compiler only complains if the implementation of B::foo() is missing, but it does not complain about a missing A::foo().

    All in all: is this a way to hide pure virtual methods?

  • Juergen
    Juergen about 11 years
    If B::foo() does not hide A::foo() then why is C allowed to NOT implement it?
  • masoud
    masoud about 11 years
    If you want get an object from C then it's must implement foo
  • Mike Seymour
    Mike Seymour about 11 years
    No, B::foo is not the same as A::foo, and does hide it (as well as overriding it).
  • Juergen
    Juergen about 11 years
    I confirm that gcc does throw the error messages, while the visual c++ compiler does not.
  • taocp
    taocp about 11 years
    @Juergen Thanks for confirming that.
  • Rasmi Ranjan Nayak
    Rasmi Ranjan Nayak over 7 years
    Is Virtual really required in class C. Can not it be just void foo() {};?
  • Shoe
    Shoe over 7 years
    According to the C++ standard, no it's not required. I find it more readable though.