Why would a virtual function be private?

13,303

Solution 1

See this Herb Sutter article as to why you'd want to do such a thing.

Solution 2

This is a pure virtual function that happens to be private. This makes it so that a derived class must implement the method. In this case Bar.

I think you may be confused b/c this is done to create "interfaces" in C++ and a lot of times people think of these as public. There are cases where you may want to define an interface that is private where a public method uses those private methods in order to ensure the order of how they are called. (I believe this is called the Template Method)

For a relatively bad example :)

class RecordFile
{
    public:
       RecordFile(const std::string &filename);

       void process(const Record &rec)
       {
           // Call the derived class function to filter out
           // records the derived instance of this class does
           // not care about
           if (filterRecord(rec))    
           {
               writeRecordToFile(rec);           
           }
       };

    private:
       // Returns true if the record is of importance
       // and should be kept
       virtual bool filterRecord(const Record &rec) = 0;

       void writeRecordToFile(const Record &rec);
};

Solution 3

ISO C++ 2003 explicitly allows it:

§10.3 states nothing about access specifier and contains even a footnote in the second clause stating in the context of virtual function overrides:

[...] Access control (clause 11) is not considered in determining overriding.

The code is fully legal.

Solution 4

I'm going to quote a brief explanation from the great C++ FAQ Lite which sums it up well:

[23.4] When should someone use private virtuals?

Almost never.

Protected virtuals are okay, but private virtuals are usually a net loss. Reason: private virtuals confuse new C++ programmers, and confusion increases cost, delays schedule, and degrades risk.

New C++ programmers get confused by private virtuals because they think a private virtual cannot be overridden. After all, a derived class cannot access members that are private in its base class so how, they ask, could it override a private virtual from its base class? There are explanations for the above, but that's academic. The real issue is that almost everyone gets confused the first time they run into private virtuals, and confusion is bad.

Unless there is a compelling reason to the contrary, avoid private virtuals.


The C++ FAQ Lite was updated in the meantime:

By the way, it confuses most novice C++ programmers that private virtuals can be overridden, let alone are valid at all. We were all taught that private members in a base class are not accessible in classes derived from it, which is correct. However this inaccessibility by the derived class does not have anything to do with the virtual call mechanism, which is to the derived class. Since that might confuse novices, the C++ FAQ formerly recommended using protected virtuals rather than private virtuals. However the private virtual approach is now common enough that confusion of novices is less of a concern.

Solution 5

The usual "academic" answer is: access specifiers and virtuality are orthogonal - one does not affect the other.

A little more practical answer: private virtual functions are often used to implement the Template Method design pattern. In languages that do not support private virtual functions, the template method needs to be public although it is not really meant to be a part of the interface.

Share:
13,303
liori
Author by

liori

Updated on June 05, 2022

Comments

  • liori
    liori about 2 years

    I just spotted this in some code:

    class Foo {
    [...]
    private:
        virtual void Bar() = 0;
    [...]
    }
    

    Does this have any purpose?

    (I am trying to port some code from VS to G++, and this caught my attention)