Search code examples
c++functionvirtualimplementation

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


I did a simple test today:

struct C{virtual void f()=0;};
void C::f(){printf("weird\n");}

The program is OK, but is weird to me, when we use =0 it means the function body should be defined in the inherited classes, but it seems I can still give it implementation function.

I tried both GCC and VC, both OK. So it seems to me this should be part of C++ standard.

But why this is not a syntax error?

A reason I could think of is like C# having both 'interface' and 'abstract' keywords, interface can't have an implementation, while abstract could have some implementations.

Is this the case for my confusion, that C++ should support such a kind of weird syntax?


Solution

  • 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;
        }
    };
    

    Technical Edit: The C++ standard requires the bodies of pure virtual functions to be defined outside of the class definition body. In other words a class member function cannot be both pure virtual and inline. The previous code example compiles on MSVC (Visual Studio), but not on GCC or CLANG.

    Clause 10.4 paragraph 2 of C++03 tells us what an abstract class is and, as a side note, the following: [Note: a function declaration cannot provide both a pure-specifier and a definition —end note]

    A pure virtual function with a body as per the C++ standard looks something like this:

    #include <iostream>
    using namespace std;
    
    class PersonBase
    {
    private:
        string name;
    public:
        PersonBase(string nameIn) : name(nameIn) {} 
    
        virtual void printDetails()=0;
    };
    void PersonBase::printDetails()
    {
        std::cout << "Person name " << name << endl;
    }