The road to coding--re-learning C + + (10): Hierarchy of Classes

Source: Internet
Author: User

1. Multiple inheritance

(1) Multiple inheritance has been a mechanism that has been criticized by many people in C + +, but it has greatly increased the flexibility of class hierarchies by looking at a simple example:

classtask{ Public:    Virtual voidPending () =0; //...};classdisplayed{ Public:        //...    Virtual voidDraw () =0;};classSatelite: PublicTask, Publicdisplayed{ Public:        //...    voidpending (); voiddraw ();};

This ensures that when satelite is treated as a task or displayed, it is still satelite::p ending () and satelite::d Raw ().

(2) Analysis of ambiguity. When a member function of the same name may be in two base classes, we can define a new function in the derived class and let the information be localized to solve the problem:

classtask{//...    Virtualdebug_info*get_debug ();};classdisplayed{//...   Virtualdebug_info*get_debug ();};classSatelite: PublicTask, Publicdisplayed{//...debug_info*Get_debug () {Debug_info*DIP1 =Task::get_debug (); Debug_info*DIP2 =Displayed::get_debug (); returnDip1->merge (DIP2); }};

And a function cannot be found in a derived class, the compiler goes to its base class.

(3) Use of claims and inheritance. When we want to be able to choose which function to invoke based on the actual parameters, we can use the declaration to introduce the function into scope:

classa{ Public:    intFint); CharFChar);};classb{ Public:        DoubleFDouble);};classAb: PublicA Publicb{ Public:    usingA::f; usingB::f; CharFChar);//A::f (char) coveredAB F (AB);};voidG (AB &AB) {Ab.f (1);//a::f (int)Ab.f ('a');//ab::f (char)Ab.f (2.0);//b::f (Double)AB.F (AB);//ab::f (AB)}

Note that the use declaration in a class definition must be a member of the base class, and the use directive cannot appear in the class definition, nor can it be used on a class.

(3) Virtual base class. In an inheritance system, virtual base classes, which are depicted by virtual, will always be represented by the same object of this class, and the base class without virtual has a child object of its own. We can call the virtual base class function only from the final derived class, making the class hierarchy clearer:

classwindow{Virtual voiddraw ();};classWindow_border:Virtualwindow{voidOwn_draw (); voiddraw ();};classWindow_menu:Virtualwindow{voidOwn_draw (); voiddraw ();};classClock: PublicWindow_border, Publicwindow_menu{voidOwn_draw (); voiddraw ();};//Draw function ImplementationvoidWindow_border::d Raw () {Window::d raw (); Own_draw ();}voidWindow_menu::d Raw () {Window::d raw (); Own_draw ();}voidClock::d Raw () {Window::d raw ();    Window_border::own_draw ();    Window_menu::own_draw (); Own_draw ();};

We can also use several derived classes to implement a virtual base class given the interface services, such as the Window class has the function Set_color () and prompt () two pure virtual functions, then we can let the Window_border class implementation Set_color () function, Window The _menu class implements the prompt () function. If two classes cover the same base class function, but they do not cover each other, this class hierarchy is wrong.

2. Access control

(1) Access control rules: Default is Private base class

If B is a private base class, then the public and protected members of B become private members of the derived class D, and only the members and friends of D can convert d* to b*.

-If B is a protected base class, then the public and protected members of B become protected members of the derived class D, and only the members and friends of the derived classes D and D can convert d* to b*.

--if B is the public base class, access control in derived Class D is the same as in B.

(2) It is not possible to use claims to obtain more access, and all must follow the access control rules.

3. Run-Time type information

(1) dynamic_cast is the specialty of a dynamic type conversion operation that handles operations where the compiler cannot determine the correctness of the conversion. dynamic_cast CONVERT returns a valid pointer when the object has the desired type, otherwise a null pointer is returned.

(2) dynamic_cast the type required to be converted must be a reference or pointer with a virtual function, which would make it easy for us to find a location for the type information of the object in the inch. A typical implementation is a "type information object" attached to an object by placing a pointer to the type information in the virtual function table of the object:

(3) The target type of the dynamic_cast does not have to be polymorphic. This allows us to wrap a specific type into a polymorphic type, such as passing it through an I/O system and then "opening the package" to take out the specific type:

class io_obj{    virtual0;}; class  Public  Public io_obj{}; void F (io_obj *Pio) {    *pd = dynamic_cast<date*>(PIO);}

In addition, the dynamic_cast of the void* type can be used to determine the starting address of the object of the polymorphic type.

(2) The result of the dynamic_cast of the reference type implicitly has the dynamic_cast itself to implement. If the type conversion fails, a Bad_cast exception is thrown.

(3) for static_cast, it cannot be cast from a virtual base class like dynamic_cast. Dynamic_cast also because the compiler cannot provide a guarantee for the storage that void* points to, and cannot convert from void*. But both have to follow the access control rules.

(4) typeID () is used to obtain an object that represents the type of the corresponding operand, which returns a reference to a type_info type, defined in <type_info>, with a simple implementation as follows:

classType_info;Consttype_info& typeid (type_name)Throw();Consttype_info& typeid (expression)Throw(Bad_typeid);classtype_info{ Public:        Virtual~Type_info (); BOOL operator==(Consttype_info&)Const; BOOL operator!=(Consttype_info&)Const; BOOLBefore (Consttype_info&)Const; Const Char* Name ()Const;//Prohibit copyingPrivate: Type_info (Consttype_info&); Type_info&operator=(Consttype_info&); //...};

(5) In general, the correct use of Rtti is mostly service code is represented by a class, and the user wants to add functionality by derivation for this class, we use Rtti to convert to the type of additional functionality called additional functionality.

4. Member Pointers and free storage

(1) A pointer to a member is not like a pointer to a variable or a function, it is not a pointer to a piece of memory. This pointer is more like an offset in a structure, or an array subscript. We can safely assign a pointer to a member of a base class to a pointer to a member of a derived class, which in turn is not possible. A static member function is not associated with any object, so a pointer to a static member is a regular pointer.

(2) in free storage, operator new () and operator delete () are static members by default, and no object is modified without the this pointer. In addition, we cannot construct fictional functions, but we can construct a virtual function that produces a class, and then call the constructor that you want to use.

The road to coding--re-learning C + + (10): Hierarchy of Classes

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.