Do All Virtual Functions Need to Be Implemented in Derived Classes

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 of Derived1, with a slightly different f(), 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 initialize object_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



Leave a reply



Submit