The first phase of C ++ view shows how to implement a class that cannot be inherited.
As follows:
# Ifdef ndebug
# Define final_class
# Else
# Define final_class: PublicVirtualPRIVATE: nonderivablehelper // The key here is that virtual cannot be inherited as long as it is virtual.
# Endif
Namespace private
{
Class nonderivablehelper
{
Protected:
Nonderivablehelper (INT) {cout <"A" <Endl;} // added ctor argument
};
}
Class nonderivable final_class
{
Public:
Nonderivable (): nonderivablehelper (0) {cout <"B" <Endl;} // pass a dummy Value
};
Class A: Public nonderivable
{
Public:
A () {cout <"C" <Endl ;}
};
Int main (INT argc, char * argv [])
{
Nonderivable N;
A;
Return 0;
}
Here, a tries to inherit the nonderivable class, but the compiler reports an error.
Underivable. CC | 55 | error: the call to 'private: nonderivablehelper () 'does not have a matching function.
Underivable. CC | 40 | Note: Alternative: Private: nonderivablehelper (INT)
Underivable. CC | 38 | Note: Private: nonderivablehelper (const PRIVATE: nonderivablehelper &)
This is why virtual inheritance is selected. When virtual inheritance is selected, the constructor skips nonderivable (): nonderivablehelper (0) and calls the constructor directly.
Nonderivablehelper (INT)
In the hierarchy of virtual inheritance, the virtual base class is always constructed before the non-virtual base class is constructed.. For more information, see http://tech.ddvip.com/2009-07/1246614951125275.html.
Even if non-virtual inheritance is performed, the base class is first constructed, but the selection of the constructor is determined by the subclass. If the subclass does not provide information, the default constructor of the base class is called.
The virtual inheritance here makes it possible to directly construct nonderivablehelper over nonderivable.
Just make a small experiment clear.
# Ifdef ndebug
# Define final_class
# Else
# Define final_class:PublicVirtualPRIVATE: nonderivablehelper// The key here is that virtual cannot be inherited as long as it is virtual.
# Endif
Namespace private
{
Class nonderivablehelper
{
Protected:
Nonderivablehelper (INT) {cout <"A" <Endl ;}// Added ctor argument
Nonderivablehelper () {cout <"! "<Endl ;}
};
}
Class nonderivable final_class
{
Public:
Nonderivable ():Nonderivablehelper (0){Cout <"B" <Endl;} // pass a dummy Value
};
Class A: Public nonderivable
{
Public:
A () {cout <"C" <Endl ;}
};
Int main (INT argc, char * argv [])
{
//;
Nonderivable N;
A;
Return 0;
}
Running result
A
B
A!
B
C
Remove virtual
That is, # define final_class:Public Private: nonderivablehelper// The key here is that virtual cannot be inherited as long as it is virtual.
Running result
A
B
A
B
C
OK. The differences between virtual inheritance and non-virtual inheritance in the calling of constructors are clear. A and! .