There is absolutely no reason for all functions to be virtual in an abstract class. For example, there is a classical pattern, when using an abstract class they implement a certain “skeleton” of a general algorithm, and with the help of virtual functions they fill in the particular details of a particular application of this algorithm. The details of the algorithm are implemented by virtual functions, and the algorithm itself is a non-virtual function. An elementary example of such a pattern could be a certain class "Program":
class Program { protected: virtual void init() {} virtual void run() = 0; virtual void done() {} public: void execute() { init(); run(); done(); } };
In this example, the actual "algorithm" itself is implemented by the execute() function, which has no reason to be virtual. The whole variety of behaviors of different "programs" is implemented by the successor classes through the overlapping of the functions init() , run() and done() , while the "algorithm" itself remains undisguable.
The behavior of virtual functions in C ++ is fundamentally based on the concept of a dynamic object type . A virtual function call is, by definition, a call in which a particular version of a function is selected based on an analysis of the dynamic type of the object used in that call. For this reason, a virtual call is possible only when the dynamic type of the object is already defined (initialized, formed, fixed - choose the term that you like). So the constructor is exactly that special function that forms , initializes the type of the object. Until such time as the constructor worked, the object does not exist yet and the type of the object is not yet determined. Those. The concept of a virtual call to such a “raw” object is not yet applicable. For this reason, in C ++ there can be no virtual constructors.
In other words, in C ++, the constructor is the same function that initializes the virtual call mechanism. Therefore, it is virtually impossible to call the constructor itself - at this point, the functionality of virtual calls has not yet been initialized.
Physically, in the ubiquitous implementation of polymorphism, the functionality of virtual functions is provided by the so-called table of virtual functions , the pointer to which is stored in each polymorphic object. So the constructor, among other things, is exactly the same and binds each polymorphic object to its correct virtual function table. Before such a binding is performed, virtuality cannot work.
Hmm ... Absolutely every class has its own destructor. But virtuality is needed precisely in order for the polymorphic deletion of an object to select the correct destructor correctly , in accordance with the dynamic type of the object being deleted. Those. if you have a pointer to the base class Base *p , which actually points to an object of the derived type Derived
Base *p = new Derived;
then when performing delete p (polymorphic deletion) you need to Derived class destructor. For this to happen, the destructor must be virtual.
If the destructor in such a situation is not virtual, then, as @VladD correctly noted in the comments, the program's behavior is not defined.
It is impossible to create an independent copy of an abstract class because the language specification forbids this. And what is the point in this creation? The abstract class is a class with "nonexistent" (unwritten) virtual functions. Why and who might need objects of such an inferior class? What do you suggest to do if the user tries to call such a non-existent virtual function? To cause undefined behavior? The authors of the language decided that it was wiser to simply prohibit the creation of independent copies of abstract classes.
At the same time, it can be said that instances of abstract classes can still be created, but only as basic sub - objects of non-abstract classes-heirs, and not as independent objects. Actually, this is the purpose of abstract classes - to serve as the base classes for successor classes.
Here you can also add that there is still a loophole that allows you to try to make a call to a nonexistent virtual function of an abstract class: it is a call to a virtual function from the constructor (or destructor) of an abstract class. To "deceive" the compiler, such a call usually has to be done via an intermediate function.
struct S { virtual void foo() = 0; void bar() { foo(); } S() { bar(); } }; struct D : S { virtual void foo() {} }; int main() { D d; }
The above code leads to indefinite behavior (practically, to the crash of the program) precisely because during the operation of the class S constructor, an attempt is made to call the nonexistent method S::foo() . One can conditionally say that during that “short time” when the constructor (or destructor) of an abstract class is working, the corresponding object is an independent abstract object with all the ensuing consequences, such as a program crash when trying to call a non-existent virtual function.
I do not understand why this question arises. It makes sense to write a constructor in an abstract class, of course, if there is work for such a constructor in this class. The constructor must initialize something. Do you have something to initialize in your abstract class? If there is - then write the designer.
Another thing is that usually in the abstract class there is nothing to initialize. Accordingly, the constructor is often not needed.
I do not understand the essence of the question. Friendliness has nothing to do with virtuality. Therefore, declaring a virtual function as a friend has exactly the same meaning as declaring any other (non-virtual) function as a friend.
Here it is worth repeating again that friendliness does not know anything about virtuality (and virtuality knows about friendship). Friendliness does not extend through the class hierarchy, i.e. The friendliness you declared will not apply to the "same" virtual function in the inheritance classes.