Pure virtual methods in derived abstract class
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 hidefoo
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;
}
};
Juergen
Updated on June 05, 2022Comments
-
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 hidefoo
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 missingA::foo()
.All in all: is this a way to hide pure virtual methods?
-
Juergen about 11 yearsIf B::foo() does not hide A::foo() then why is C allowed to NOT implement it?
-
masoud about 11 yearsIf you want get an object from
C
then it's must implementfoo
-
Mike Seymour about 11 yearsNo,
B::foo
is not the same asA::foo
, and does hide it (as well as overriding it). -
Juergen about 11 yearsI confirm that gcc does throw the error messages, while the visual c++ compiler does not.
-
taocp about 11 years@Juergen Thanks for confirming that.
-
Rasmi Ranjan Nayak over 7 yearsIs
Virtual
really required in class C. Can not it be justvoid foo() {};
? -
Shoe over 7 yearsAccording to the C++ standard, no it's not required. I find it more readable though.