Do ALL virtual functions need to be implemented in derived classes?
Derived classes do not have to implement all virtual functions themselves. They only need to implement the pure ones.1 That means the Derived
class in the question is correct. It inherits the bar
implementation from its ancestor class, Abstract
. (This assumes that Abstract::bar
is implemented somewhere. The code in the question declares the method, but doesn't define it. You can define it inline as Trenki's answer shows, or you can define it separately.)
1 And even then, only if the derived class is going to be instantiated. If a derived class is not instantiated directly, but only exists as a base class of more derived classes, then it's those classes that are responsible for having all their pure virtual methods implemented. The "middle" class in the hierarchy is allowed to leave some pure virtual methods unimplemented, just like the base class. If the "middle" class does implement a pure virtual method, then its descendants will inherit that implementation, so they don't have to re-implement it themselves.
Why would I want to implement virtual functions without implementation in an abstract class?
virtual void f(); // virtual member function
virtual void g() = 0; // pure abstract member function
A class with at least one pure virtual member function is an abstract class, and cannot be constructed itself, which is often desired (only non-abstract, "concrete" if you will, derive classes should be able to be constructed);
struct Abstract {
virtual void g() = 0;
};
struct NonAbstract {
virtual void f() {}
};
int main() {
NonAbstract na{}; // OK
Abstract a{}; // Error: cannot declare variable 'a'
// to be of abstract type 'Abstract'
}
Abstract classes are typically used polymorphically, to allow dynamic dispatch to derived object methods:
struct Derived : public Abstract {
void g() override {} // #1
}
void h(Abstract const& obj) {
obj.g(); // dynamic dispatch
}
int main() {
Derived d{};
h(d); // Will result in invoke #1
}
c++ Pure virtual functions dependent on derived classes
It is possible to concoct such a thing with CRTP
class BoundingBox;
class BoundingSphere;
class Shape
{
public:
virtual bool isIntersecting(const BoundingBox&) const = 0;
virtual bool isIntersecting(const BoundingSphere&) const = 0;
};
class BoundingVolumeBase
{
public:
virtual bool checkIntersection(const Shape&) const = 0;
virtual ~BoundingVolumeBase();
};
template<class Derived>
class BoundingVolume : public BoundingVolumeBase
{
bool checkIntersection(const Shape& shape) const override
{
return shape.isIntersecting (static_cast<const Derived&>(*this));
}
};
class BoundingBox : public BoundingVolume<BoundingBox> {
// ...
};
class BoundingSphere : public BoundingVolume<BoundingSphere> {
// ...
};
Now if we invent a new kind of BoundingVolume
, it will not compile until a new function is added to Shape
.
class BoundingCylinder : public BoundingVolume<BoundingCylinder> {
// ...
};
BoundingCylinder bc; // <-- this will not compile
It is not necessary to do it this way. Any method that uses virtual functions as the sole kind of type-based dispatch will work (you will likely end up with something roughly equivalent to the above anyway). If you depend on typeid
or on a custom type identifier, you may encounter problems though.
The downside of this method is mutual dependence of class Shape
and all concrete kinds of BoundingVolume
.
C++ virtual keyword for functions in derived classes. Is it necessary?
They are exactly the same. There is no difference between them other than that the first approach requires more typing and is potentially clearer.
Pure virtual function with implementation
A pure virtual
function must be implemented in a derived type that will be directly instantiated, however the base type can still define an implementation. A derived class can explicitly call the base class implementation (if access permissions allow it) by using a fully-scoped name (by calling A::f()
in your example - if A::f()
were public
or protected
). Something like:
class B : public A {
virtual void f() {
// class B doesn't have anything special to do for f()
// so we'll call A's
// note that A's declaration of f() would have to be public
// or protected to avoid a compile time problem
A::f();
}
};
The use case I can think of off the top of my head is when there's a more-or-less reasonable default behavior, but the class designer wants that sort-of-default behavior be invoked only explicitly. It can also be the case what you want derived classes to always perform their own work but also be able to call a common set of functionality.
Note that even though it's permitted by the language, it's not something that I see commonly used (and the fact that it can be done seems to surprise most C++ programmers, even experienced ones).
C++ pure virtual functions implementation in derived class
Change:
class api_top : public api_base
to class api_top : public virtual api_base
and:
class imp_base
to class imp_base : public virtual api_base
Then it works.
To understand this, see: virtual inheritance. And yes (just saw Ext3h's post), use the override
keyword.
Avoiding Defining a pure virtual function in c++ in immediate derived class?
No one forces you to implement pure virtual
functions, so you don't have to. Your class will just be abstract. In a derived class, just leave the declaration out or re-declare it as virtual pure.
struct Base
{
virtual void foo() = 0;
};
//this is OK, X is abstract
struct X : Base
{
};
//this is also OK, redundant, and Y is abstract
struct Y : Base
{
virtual void foo() = 0;
};
How to avoid a virtual function for a single derived class implementation?
If you are sure that object_1
always points to a Derived1
, then make it a std::shared_ptr<Derived1> object1
. And if the sole purpose of Base::f()
is for Derived1
, make it non-virtual and remove it from the classes that don't need it.
But if one of those assumptions is not true, keep it as it is:
Making an extra test to check if the class is
Derived1
before calling a non-virtual function is not more efficient than calling directly a virtual function. If you don't trust me, make a benchmark. Moreover, if in the future you'd have a further specialization ofDerived1
, with a slightly differentf()
, you'd not have to worry.Assuming that it's always
Derived1
and just statically down-casting is risky. As said, if you're so sure, just declare it as such (go to first paragraph), and make a (safe) downcasting when you initializeobject_1
.
Remark: While it may seem weird at beginning to have a f()
that is useless in most cases, it is in fact a common practice when using polymorphism with the tell, don't ask paradigm. A very typical example is when using the template method pattern.
Related Topics
Why Is the Size of Array as a Constant Variable Not Allowed in C But Allowed in C++
Create a Reverse Linkedlist in C++ from a Given Linkedlist
Windows Unicode C++ Stream Output Failure
How to Write to Middle of a File in C++
How to Optimize Matrix Multiplication (Matmul) Code to Run Fast on a Single Processor Core
When Extending a Padded Struct, Why Can't Extra Fields Be Placed in the Tail Padding
Detect Gcc Compile-Time Flags of a Binary
Why Are Forward Declarations Necessary
Is There a Limit of Stack Size of a Process in Linux
Convert a Unicode String in C++ to Upper Case
Can a C++ Compiler Re-Order Elements in a Struct
How to Restart My Own Qt Application