问题
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:
See this Herb Sutter article as to why you'd want to do such a thing.
回答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); };
回答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.
回答4:
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.
回答5:
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.
回答6:
It is a pure virtual function. Any final implementation that is dervied from "Foo" MUST implement the "Bar" function.
回答7:
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,
回答8:
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.
来源:https://stackoverflow.com/questions/1133955/why-would-a-virtual-function-be-private