C++ Pure Virtual Function Have Body

C++ pure virtual function have body

Your assumption that pure virtual function cannot be called is absolutely incorrect. When a function is declared pure virtual, it simply means that this function cannot get called dynamically, through a virtual dispatch mechanism. Yet, this very same function can easily be called statically, non-virtually, directly (without virtual dispatch).

In C++ language a non-virtual call to a virtual function is performed when a qualified name of the function is used in the call, i.e. when the function name specified in the call has the <class name>::<function name> form.

For example

struct S 
{
virtual void foo() = 0;
};

void S::foo()
{
// body for pure virtual function `S::foo`
}

struct D : S
{
void foo()
{
S::foo();
// Non-virtual call to `S::foo` from derived class

this->S::foo();
// Alternative syntax to perform the same non-virtual call
// to `S::foo` from derived class
}
};

int main()
{
D d;

d.S::foo();
// Another non-virtual call to `S::foo`
}

What's the use of the body of a pure virtual function in c++?

It is used in the exact way you mentioned in the question, that there is some common logic that can be reused by the derived classes but at the same time you want to force the derived classes to provide the implementation for the non-common part.

Use-cases of pure virtual functions with body?

The classic is a pure virtual destructor:

class abstract {
public:
virtual ~abstract() = 0;
};

abstract::~abstract() {}

You make it pure because there's nothing else to make so, and you want the class to be abstract, but you have to provide an implementation nevertheless, because the derived classes' destructors call yours explicitly. Yeah, I know, a pretty silly textbook example, but as such it's a classic. It must have been in the first edition of The C++ Programming Language.

Anyway, I can't remember ever really needing the ability to implement a pure virtual function. To me it seems the only reason this feature is there is because it would have had to be explicitly disallowed and Stroustrup didn't see a reason for that.

If you ever feel you need this feature, you're probably on the wrong track with your design.

Adding a body to a pure virtual/abstract function in C++?

Pure virtual function can have a body, but the fact that you declare them pure virtual is exactly to say that a derived implementation is required.

You can execute the pure virtual method from a derived method (using an explicit BaseClass::method()) but still you have to provide an implementation.

Not being able to instantiate a class with a pure virtual method that has not been overriden is the main point of the pure virtual declaration. In other words the idea of declaring a method pure virtual is to ensure that the programmer will not forget about providing its implementation.

What is the point of a pure-virtual member function with function body?

What are sensible use cases for this?

If the function has a sensible default implementation, or a partial implementation of whatever is relevant to the base class, but you still want to force derived classes to override it, that's a good place to put it.

Also, as noted in the comments, you might want to force a class with no pure virtual functions to be abstract. You can do this by making the destructor pure virtual; but the destructor must have a body, whether or not it's pure virtual.

when would A::foo ever be called?

It can only be called non-virtually; for example:

struct B : A {
void f(int i) const {
A::foo(i); // non-virtual call
// Do the B-specific stuff
}
};

why is this the correct/best implementation?

The alternative would be to invent a new name for the partial/default implementation, in addition to an unimplemented pure virtual function.

Are there any differences here between C++03 and C++11?

No.

Can I avoid a pure virtual function with a body in this case

Sounds to me like all you really need is a virtual destructor for parent.

With a virtual dtor, deleting via a parent pointer the compiler will correctly call the derived class destructor.

It that's all you actually need and I understood your question correctly, then adding

 virtual ~parent() = default;

to your base class should do the trick.

Why does C++ support pure virtual functions with an implementation?

C++ Supports pure virtual functions with an implementation so class designers can force derived classes to override the function to add specific details , but still provide a useful default implementation that they can use as a common base.

Classic example:

class PersonBase
{
private:
string name;
public:
PersonBase(string nameIn) : name(nameIn) {}

virtual void printDetails() = 0
{
std::cout << "Person name " << name << endl;
}
};

class Student : public PersonBase
{
private:
int studentId;
public:
Student(string nameIn, int idIn) : PersonBase(nameIn), studentId(idIn) { }
virtual void printDetails()
{
PersonBase::printDetails(); // call base class function to prevent duplication
std::cout << "StudentID " << studentId << endl;
}
};

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).



Related Topics



Leave a reply



Submit