Note 9-Inheritance

Source: Internet
Author: User
The base class derived class (derived class) 1 C ++ supports several methods of polymorphism: A uses an implicit conversion, convert from "pointer or reference of a derived class" to "pointer or reference of its common base class type" B. Use the virtual function mechanism C. Use the dynamic_cast and typeid operators 2. the class specified in the derived table must first defined, can be specified as the base class. For example, the forward Declaration of the following query is insufficient to use it as the base class // error: the query must have been defined as a class query; Class namequery: public query {...}; 3. The forward declaration of a derived class cannot include its derived table, but only the class name -- the same as that of a non-derived class. For example, the following namequery Forward Declaration causes a compilation time error: // error: the Forward Declaration cannot contain the derived table class namequery: public query of the derived class; the correct Forward Declaration is as follows // The forward declaration of a derived class and a non-derived class lists only class queries; Class namequery; 4 the abstract base class can only define pointers and reference 5 class diffident {public: void turn_aside ();//...}; class shy: Public diffident {public: // hides the void turn_aside () Visibility of diffident: turn_aside ();//...}; class shy: Public diffident {public: // OK: in the Standard C ++, the using declares // creates an overloaded set of base class and derived class members void mumble. (String whatyasay); Using diffident: mumble; //...}; in fact, the using declaration introduces each named Member of the base class to the domain of the derived class. The Using Declaration for a member function cannot specify the parameter list, but only the member function name can be specified. 6. A derived class cannot access the protected member of another independent base class object, for example, boolnamequery: Compare (const query * pquery) {// OK: int mymatches = _ loc. size (); // error: No "directly access another independent query // protected member of the object" right int itsmatches = pquery-> _ loc. size (); Return mymatches = itsmatches ;} 7 consider the following initialization: Use the address of the namequery object of a derived class to initialize a query base class pointer query * pb = new namequery ("sprite "); if we call a virtual function defined in the query base class, such as Pb-> eval (); // call namequery: EV Al () calls the derived namequery class instance. In addition to the virtual functions declared in the query base class and rewritten in the namequery class, we cannot directly access the namequery members through Pb: a. If both query and namequery declare a non-virtual member function with the same name, the query instance is always called through PQ. B. Similarly, if both query and namequery declare a data member with the same name, the query instance is always accessed through PQ. C. If namequery introduces a virtual function that does not exist in the query, such as suffix (), trying to call it through PQ will lead to a compilation time error: // error: suffix () it is not a query member Pb-> suffix (); d Similarly, if we try to access the data member or non-virtual member function of namequery through PQ, a compilation time error will also be generated: // error: _ name is not the query member Pb-> _ name; in this case, it does not work even if the Members to be accessed are limited. // error: query does not have the namequery base class Pb-> namequery: Name (); 8 if a derived class wants to directly access the private members of its base class, the base class must explicitly declare the derived class as a friend, such as class query {friend class namequery; public: //...}; construction of the binary base class and the derived class 1 the derived class is composed of one or Multiple Base-class sub-objects and derived-class parts: for example, namequery consists of a query sub-object and a string member class object. To illustrate the behavior of the derived class constructor, we introduce a built-in data member class namequery: public query {public ://... protected: bool _ present; string _ name;}; 2 first, consider the case where the namequery class constructor is not defined. In this case, when a namequery object is defined: namequery NQ; first, the default Query Class constructor is called, then, call the default string class constructor to correspond to the member Class Object _ name. _ Present is not initialized, which is a potential Program The root cause of the error. 3. The Calling sequence of constructor is always as follows: a base class constructor. If there are multiple base classes, the calling sequence of the constructor is the sequence in which a class appears in the class derived table, rather than the sequence in the member initialization table. B Member class object constructor. If there are multiple Member class objects, the calling sequence of the constructor is the order in which objects are declared in the class, rather than the order in which they appear in the member initialization table. C derived class constructor 3 base class constructor if the class member is an object, this object will automatically call its own default constructor. A derived class constructor can only legally call the constructor of its direct base class. 4. The Calling sequence of the destructor of the derived class is the opposite to that of its constructor. Three base classes and derived classes virtual functions 1 by default, the member functions of the class are non-Virtual. When a member function is non-virtual, a Class Object (pointer or reference) is used) the called member function is the member function defined in the class object. 2 when a member function is virtual, the member function called through a class Object (pointer or reference) is a member function defined in the dynamic type of the Class Object. However, as it occurs, the static and dynamic types of A Class Object are the same. Therefore, the virtual function mechanism works as expected only when pointers and references are used. 3 using a base class object does not retain the type identity of the derived class, for example, namequery NQ ("Lilacs"); // OK: But NQ is "cut" into a query sub-object query qobject = NQ; 4 void print (query object, const query * pointer, const query & reference) {// you can determine which print () instance pointer to call/> Print () until the runtime (); reference. print (); // always call query: Print () object. print () ;}int main () {namequery Firebird ("Firebird"); print (Firebird, & Firebird, Firebird );} calls through pointer and reference are parsed into their dynamic types. In this example, all of them call namequery: Print (). When an object is called, query: Print () is always called (). 5. When introducing the base class of a virtual function for the first time, you must specify the virtual keyword in the class declaration. If the definition is placed outside the class, the keyword virtual cannot be specified again. The correct definition must not include the keyword virtual6 Ural. The declaration of the function in the base class and the derived class should be exactly the same (parameter type, number of parameters, return value type ). With one exception, the return value of a derived class instance allows the base class instance to return a total of derived class types. 7 classes that contain (or inherit) one or more pure virtual functions are recognized by the compiler as abstract base classes. If you try to create an independent class Object of the abstract base class, an error will be reported during compilation. Similarly, calling a pure virtual function through a virtual mechanism is also incorrect. 8. When a virtual function is called using a domain-like operator, the virtual mechanism is changed, and the virtual function is statically parsed at the time of compilation. Query * pquery = new namequery ("Dumbo"); // call ISA () dynamically through a virtual mechanism // call namequery: ISA () instance pquery-> ISA (); // call ISA statically at Compilation Time // call query: ISA instance pquery-> query: ISA (); 9 if the default real parameter of a virtual function is called through a pointer or reference of the base class, the function is determined at the runtime. However, the default real parameters passed to Foo () are not determined at the runtime, but determined at the compilation time based on the type of the object to be called. When Foo () is called through Pb, the declaration of base: Foo () in the default real parameter is 1024. When Foo () is called through PD, the default real parameter is determined by the declaration of derived: Foo (), which is 2048. # Include <iostream> class base {public: Virtual int Foo (INT ival = 1024) {cout <"base: Foo () -- ival:" <ival <Endl; return ival ;}//...}; class derived: public base {public: Virtual int Foo (INT ival = 2048) {cout <"derived: Foo () -- ival:" <ival <Endl; return ival ;}//...}; int main () {derived * Pd = new derived; base * pb = Pd; int val = Pb-> Foo (); cout <"Main (): Val through base: "<Val <Endl; val = Pd-> Foo (); cout <"Main (): Val through derived:" <Val <Endl ;} compile and run the program to generate the following output: derived: Foo () -- ival: 1024 main (): Val through base: 1024 derived: Foo () -- ival: 2048 main (): Val through derived: 2048 if you call a derived class instance through a base class pointer or reference, the default arguments passed to it are specified by the base class, so why do we need to specify the default real parameter in a derived class instance? 10 virtual destructor void doit_and_bedone (vector <query *> * PVEC) {//... For (; it! = End_it; ++ it) {query * PQ = * it ;//... delete PQ ;}} to make the function run correctly, you must call the dynamic type destructor pointed to by PQ when applying the delete expression. Therefore, you must declare the Query Class destructor as a virtual: Class query {public: Virtual ~ Query () {Delete _ solution ;}//...}; if PQ points to an andquery object Delete PQ, the virtual mechanism is used to call the andquery destructor, and then the binaryquery destructor is statically called, the query destructor is also called statically. The destructor of the base class should not be protected. 11 virtual new operator cannot be declared as virtual because it is a static member function and is applied to unused memory before constructing class objects. 12. If a virtual function is called in the base class constructor, the base class and the derived class define the instance of the function, what will happen? Which function instance should be called? If you can call a derived class instance of a virtual function and access any member of the derived class, the call result is logically undefined. The program may crash. To prevent this, the virtual instances called in the base class constructor are always active in the base class. In fact, in a base class constructor, a derived class object is only a base class object. For a derived class object, this is also true in the basic class destructor: The derived class is also undefined, but this time it is not because it has not been constructed, but because it has been destroyed. Initializing by members 1 "initializing another object of this class with one class object" occurs in the following scenarios: A uses a class object to initialize another class object. B transmits a class object as a real parameter to a function and returns the definition of a Class Object C non-empty sequence container type. For example: // The five string copy constructors are called VECTOR <string> SVEC (5). In this example, use the string default constructor to create a temporary object, then, use string to copy the constructor. The temporary object is copied to the five elements of the vector in sequence. D. Insert a class object to a container type, for example, SVEC. push_back (string ("Pooh"); 2 it is not allowed to initialize a by members to declare the copy constructor as private, this prevents initialization by Members from occurring anywhere in the Program (except for the member functions and Friends of the class) B by intentionally not providing a definition (however, we still need the Declaration in step 1) to prevent the class member function and the element from being initialized by members. Class 3 object member initialization a checks Each member by default according to the member initialization. If the Member is of the built-in or composite data type, the initialization from the member to the member is executed directly. B. If the Member is an object, check whether the object provides a copy constructor. If the Member is provided, call the object. Otherwise, initialize the object by the member .... recursion .. 4. Initialize all member class objects in the member initialization table.

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: info-contact@alibabacloud.com 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.