tags:

views:

794

answers:

8

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)

+1  A: 

It is a pure virtual function. Any final implementation that is dervied from "Foo" MUST implement the "Bar" function.

Goz
except it is marked as 'private'. The OP did not make his question clear, and I had to look at it for a second or two before I realized it was marked as private, so +1 to negate the -1.
Ed Swangren
+1  A: 

It makes the function pure virtual as opposed to virtual.

No implementation is provided by default and the intent is that the function implementation must be specified by an inheriting class. This can be overriden however.

You sometimes see complete classes where all member functions are specified as pure virtual in this manner.

These are Abstract Base Classes, sometimes referred to as Interface Classes, and the designer of the ABC is saying to you, "I have now idea how this functionality would be implemented for all specialisations of this base class. But, you must have all of these defined for your specialisation to work and you know how your object should behave".

Edit: Oops, just spotted the fact that the member pure virtual function is private. (Thanks Michael) This changes things slightly.

When this base class is inherited using private inheritance it changes things. Basically what the designer of the base class is doing is saying is that, when your derived class calls a non-private function in the base class. part of the behaviour has been delegated to your specialisation of the function in your derived class. The non-private member is doing "something" and part of that "something" is a call, via the pure virtual base class function, to your implementation.

So some public function in Foo is calling the Bar function inside Foo, and it is relying on the fact that you will provide a specialised implementation of the Bar function for your particular case.

Scott Meyers refers to this as "implemented in terms of".

BTW Just chuckling about the number of answers that were quickly deleted by people who also didn't see the "fine print" in the question! (-:

HTH

cheers,

Rob Wells
+18  A: 

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

Greg Rogers
better paraphrase or sum up the answer in your own words. distributed nature ftw. ;)
wilhelmtell
No, better not. I don't know what Greg's pedagogic skills are like, but I doubt they are better than Sutters.
anon
So essentially the point here is to enforce the template method pattern? So that the derived class can override the method, but only the base class can ever call it?I guess that's useful, but since the derived class can just create its own internal method and call that from Bar(), I'm not sure if that qualifies as more than a suggestion.
jprete
Herb Sutter isn't the easiest to read here, so a summary would be nice. But his topic is really detail-oriented, so I don't know that it would be possible or helpful. Sutter requires a certain level of experience before it becomes clear why he is right.
sheepsimulator
@sheep Sutter is commonly seen as one of the best and clearest writers on C++ around. I've certainly never come across anyone much better.
anon
The main justification he uses is that it separates interface (public functions) from implementation (virtual functions). To get into detail beyond that you really just have read the article - it's a great read IMO.
Greg Rogers
A: 

The only purpose it seems to serve is to provide a common interface.

BTW even though a function is declared as private virtual, it can still be implemented and called with the class instance or from friends.

Nonetheless, this sort of things usually meant to serve as interface, yet I don't do it this way.

+1  A: 

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.

Idan K
I think Cline and Sutter disagree here. See the link in Greg Rogers' answer.
Fred Larson
This is why I dislike the C++ FAQ, its full of opinions that are sometime just silly, and goes against best practices as defined by some of the leading thinkers in the field. See Herb Sutters answer for a much better explanation that has the opisite opinion.
Martin York
The standard stream library is also a great place to see examples of private virtual funcitons with public non virutal that use them.
Martin York
-1: Many things confuse new C++ programmers. Do we discourage them from using such things. No, of course not because if we did that they would *stay* new C++ programmers. What a load of nonsense.
Troubadour
@Martin Agree strongly. Lots of things the FAQ says make me grind my teeth! But I suppose it's better than nothing.
anon
I probably agree with all the comments made here, I wasn't aware of it's 'real' usage before. But I think that to the people the C++ FAQ is directed at, the answer it provides is good. The thing it's probably missing is a reference to Sutter's article rather than saying it's useless.
Idan K
+3  A: 

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.

Nemanja Trifunovic
+5  A: 
RC
I don't get it, because private methods are not visible in derived classes. How can a derived class override a method that it cannot "see", or call, or access in any way?
abelenky
+1 - You've given practical reasons for Herb Sutter's argument.
sheepsimulator
Abelenky, you've pointed out the primary source of confusion regarding private virtuals, but the fact is that you don't have to be able to *call* a function to be able to *define* it. This lets the base class tell its descendants, "Provide me a function, but I alone shall decide when to call it."
Rob Kennedy
FYI, you're missing a semicolon after the ending brace on the class declaration. ;)
Seth Johnson
+2  A: 

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.

Regards,
Ovanes

ovanes