C ++ 3. Exploring inheritance Technologies

Source: Internet
Author: User

 

Explore inheritance Technology

 

 

 

This article is based on the inheritance technology that everyone knows to enhance some knowledge.

 

 

 

Inherited customer view:

Super

Except Sub objects are Super objects because Sub is inherited from Super.

Sub

A pointer to an object or reference an object that can reference the declared class or any of its subclass objects. For example, a pointer to Super can actually point to a Sub object, and so can a reference. The Customer Code still only accesses methods and data members in Super, but through this mechanism, the code that operates on Super can also operate on Sub.

Super * SuperPoint = new Sub ();

 

 

 

Inherited subclass View:

 

Subclass (public inheritance) can access the public and protected methods and data members of the superclass.

 

 

 

Overwrite method:

Only methods declared as virtual in a superclass can be correctly overwritten by the quilt class.

A good experience is that all methods are declared as virtual (except constructors), so you do not need to worry about whether the override method is valid. The only drawback is the sacrifice of performance.

Syntax: Re-declare it in the subclass definition. In the subclass implementation file, redefine. In superclasses and subclasses, virtual keywords are not required before the function is defined. You can add them to the declaration of the class definition.

 

If the subclass does not want to overwrite the method in the subclass of the quilt class, you do not need to add the virtual keyword to the method declaration in the subclass. However, it is best to add the virtual keyword to the subclass for further extension.

For example:

Class Super

{

Public:

... Code...

Virtual void someMethod ();

... Code...

};

Void Super: someMethod ()

{

Cout <"Super's method." <endl;

}

Class Sub: public Super

{

Public:

... Code...

Virtual void someMethod ();

Virtual void otherSomeMethod ();

... Code...

};

Void Sub: someMethod ();

{

Cout <"Sub's method." <endl;

}

 

 

 

 

Customer view of the coverage method:

After overwriting, Super and Sub objects can be called for the someMethod () method, but the behavior is different. For pointer or reference objects that can reference a class or any subclass. The object itself knows which class it actually belongs to, so as long as the method is declared using virtual, the correct method will be called.

Consider the following:

Super mySuper;

Sub mySub;

Super * superPoint = & mySub;

Super & ref = mySub;

Super obj = mySub;

MySuper. someMethod ();

MySub. someMethod ();

SuperPoint-> someMethod ();

Ref. someMethod ();

Obj. someMethod ();

The output is as follows:

Super's method ."

Sub's method.

Sub's method.

Sub's method.

Super's method ."

 

Note: even if the pointer and reference of a superclass know that they are actually a subclass object, they cannot call a subclass method or member that is not defined in the superclass.

For:

Ref. otherSomeMethod (); // bug

 

For non-pointer and non-referenced objects, it does not know which class it is. In this way, the following aObj object will lose some knowledge in the subclass.

Sub mySub;

Super aObj = mySub;

AObj. someMethod ();

Output:

Super's method ."

 

To sum up, it is equivalent to think of the Super object as a box, and Sub as another bigger box (because the subclass adds some of its own content ). The box does not change when Sub references or pointers are used, but a new method is used for access. However, when a Sub is forcibly converted to Super, it will throw some unique Sub content before it can be put into a small box.

 

 

 

Consider parent class:

1. Parent constructor:

The creation sequence of the objects defined by C ++ is as follows:

A. If yes, first construct the base class.

B. Non-static data members are constructed in the declared order.

C. Execute the constructor.

Note that the parent class constructor is automatically called by the system. If the parent class has a default constructor, C ++ automatically calls the constructor. If the parent class does not have a default constructor, or you want to use another constructor, You can chain the constructor, just like initializing data members in the list.

For example:

Class Super

{

Public:

Super (int I );

};

Class Sub: public Super

{

Public:

Sub ();

};

Sub: Sub (): Super (7)

{

... Code...

}

If you pass your data member as a parameter to the parent class constructor, this is not acceptable because you can call the parent class constructor before initializing your own data member. If so, the passed data member is not initialized.

 

 

2. Parent destructor

Because the Destructor cannot contain parameters, C ++ automatically calls the Destructor for the parent class. The order of revocation is the opposite of the construction order.

A. Call the destructor

B. delete data members in reverse order.

C. If a parent class exists, parse the parent class

Note that, as an experience, all destructor should be declared using the virtual keyword. Otherwise, an error may occur. Consider: if the code may call the delete operation on a superclass pointer, but this superclass pointer actually points to a subclass object, the starting position of the Destructor chain is incorrect.

 

 

3. reference the data of the parent class

In the subclass, the names of functions and data members may be ambiguous, especially for multi-inheritance. C ++ provides a mechanism to eliminate the name ambiguity between two classes: the scope parsing operator.

When override a method in a subclass, is it actually replacing the original code that is of interest to other codes? However, the methods in the parent class still exist and may be used. The method in the subclass must call the method in the parent class (the method subclass overwrites the method). You must add the parent class name and the scope parsing operator.

For example:

Class Super

{

Public:

... Code...

Virtual string doSomething () {return "Super ";}

... Code...

};

Class Sub: public Super

{

Public:

... Code...

Virtual string doSomething () {return "Sub" + Super: doSomething ();}

Virtual void otherSomeMethod ();

... Code...

};

 

 

4. Forced conversion to the upward type and forced conversion to the downward type

Forced conversion to upward type:

The following will cause Cutting

Super mySuper = mySub;

No cutting will happen below

Super * superPoint = & mySub;

Super & ref = mySub;

To sum up, use a pointer or reference pointing to a superclass to avoid cutting during forced conversion of the upward type.

 

 

Forced downward type conversion:

Consider the following:

Void presumptuous (Super * inSuper)

{

Sub * mySub = static_cast <Sub *> (inSuper );

... Other code...

}

If the person who compiled this method calls this function, it may be okay, because he knows that this function wants the parameter type to be Sub *. If someone else calls the singular number, a Super * will be passed to it, and the type conversion of parameters will not be completed during the compilation check, the function blindly assumes that inSuper is actually a pointer to a Sub object.

Downward type conversion is sometimes necessary. In a controllable environment, downward type forced conversion can be effectively used. Dynamic_cast should be used to prevent meaningless type conversion by using the built-in knowledge of this type of object. If the pointer cannot be dynamically converted, the pointer value is NULL instead of pointing to meaningless data. If dynamic_cast is not used for Object Reference, an std: bad_cast exception is thrown.

To sum up, use forced downward type conversion only when necessary and guaranteed to use dynamic type conversion.

 

 

 

Inheritance for Polymorphism

 

 

Pure Virtual Methods and abstract base classes:

A pure virtual method is an explicitly undefined method in the class definition. Classes that contain pure virtual methods are called abstract classes. abstract classes cannot be instantiated, but can still use pointers and references of the abstract class type.

Syntax: virtual string getString () const = 0;

If you want to implement mutual conversion between two sibling classes, you can add a Type constructor to the sibling class, which looks like a copy constructor, however, the copy constructor references objects of the same type, while the Type constructor references objects of the sibling class.

For example:

Class SpreadsheetCell

{Code };

Class StringSpreadsheetCell: public SpreadsheetCell

{

Public:

StringSpreadsheetCell ();

StringSpreadsheetCell (const DoubleSpreadsheetCell & inDoubelCell );

};

Class DoubleSpreadsheetCell: public SpreadsheetCell

{Code };

Given DoubleSpreadsheetCell, StringSpreadsheetCell can be easily constructed using the Type constructor. But do not be confused by type conversion. Conversion from one sibling class to another does not work. Unless the type conversion operator is overloaded.

In this way, two StringSpreadsheetCel and one StringSpreadsheetCell are implemented.

A DoubleSpreadsheetCell and two DoubelSpreadsheetCel can be added to write a common operator + overload.

Const StringSpreadsheetCell operator + (const StringSpreadsheetCell & lhs, const StringSpreadsheetCell & rhs)

{Code}

 

 

 

Multiple inheritance:

 

 

Inherit from multiple classes:

Class A {code };

Class B {code };

Class C: public A, public B {};

Objects C Support all public methods and data members in A and B.

Class C methods can access protected data and methods in A and B.

Objects C can be converted to objects A and B.

When a c object is created, the default constructor of A and B is automatically called. The Calling sequence is listed in the order of the two classes in the class definition.

When the C object is revoked, the Destructor A and B are automatically called. The Calling order is the opposite to the list order of the two classes in the class definition.

 

 

Naming conflicts and binary base classes:

 

 

Name ambiguity:

If both A and B have A public eat () method, once the C object calls the eat () method, it will produce ambiguity (but also A data member with the same name ).

Solve this ambiguity:

1. static_cast <A> (Acc. eat (); // generate A cut by converting up to call the eat () method of

2. Acc. A: eat (); // call the eat () method of A using the scope resolution operator.

Another cause of the problem of ambiguity is that the class inherits twice from the same class.

Class A {code };

Class B: public A {code };

Class C: public A, public B {};

 

 

Binary base class:

Multiple parent classes have their own parent classes.

Using this inheritance system, it is best to make the upper-layer parent class an abstract base class, And all methods are declared as pure virtual methods.

 

 

 



From my dream pursued by me

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.