Inheritance of C + + three major features

Source: Internet
Author: User

Original address: https://qunxinghu.github.io/2016/09/12/C++%20%E4%B8%89%E5%A4%A7%E7%89%B9%E6%80%A7%E4%B9%8B%E7%BB%A7%E6%89%BF/

Basic concepts

Inherited
: The inheritance of classes is that the new classes get the existing features from existing classes. The original class is called a base class or parent class, and the resulting new class is called a derived class or subclass.

Basic syntax

Declaration of a derived class:

class 派生类名:继承方式 基类名1, 继承方式 基类名2,...,继承方式 基类名n{    派生类成员声明;};

In C + +, a derived class can have multiple base classes at the same time, which is called multiple inheritance. If a derived class has only one base class, it is called single inheritance. Derived classes inherit all members of the base class except constructs and destructors.

How classes are inherited


The inheritance method specifies how to access the members inherited by the base class. The way of inheritance is public, private, protected. If the inheritance method is not shown, the default is private inheritance. inheritance specifies the access rights of derived class members and out-of-class objects to members inherited from the base class.

    • Public inheritance
      When a class inherits from a public inheritance, the access properties of the base class's public and protected members are unchanged in the derived class, and the private members of the base class are inaccessible. That is, the public and protected members of the base class are inherited into the derived class as public members and protected members of the derived class . Other members of the derived class can access them directly. The private members of the base class cannot be accessed by either the members of the derived class or the object of the derived class.
    • Private inheritance
      When a class inherits by private inheritance, both public and protected members in the base class appear in the derived class as private memberships , and the private members of the base class are inaccessible in the derived class. The public and protected members of the base class are inherited as private members of the derived class, and other members of the derived class can access them directly, but objects outside the class that are derived from the class cannot be accessed. A private member that inherits from a base class cannot be accessed either by a member of a derived class or by an object of a derived class. After multiple private inheritance, members of the base class become inaccessible. Therefore, private inheritance is less used.
    • Protect inheritance
      In protection inheritance, both public and private members of the base class appear in the derived class as protected members , and private members of the base class are inaccessible. Other members of the derived class can access public and protected members that inherit from the base class directly, but the private members of the base class cannot be accessed by an object of the derived class outside the class, regardless of the members of the derivation class or the object of the derived class.
Constructors for derived classes
    1. The initialization of a member inherited from a base class in a derived class is still done by the constructor of the base class , and the new member in the derived class is initialized in the constructor of the derived class.
      Syntax for derived class constructors:

cpp?linenums 派生类名::派生类名(参数总表):基类名1(参数表1),基类名(参数名2)....基类名n(参数名n),内嵌子对象1(参数表1),内嵌子对象2(参数表2)....内嵌子对象n(参数表n) { 派生类新增成员的初始化语句; }

Note: The initialization order of constructors is not performed in the order above, but is initialized according to the order of the declarations.

    1. If there are no constructors in the base class without parameters, the base class constructor must be called in the constructor of the derived class to initialize the base class members.
    2. The order in which the derived class constructor executes:
      1. Call the base class constructor, in the order in which they are declared when they are inherited (from left to right);
      2. Calls the constructors of the inline member objects, in the order in which they are declared in the class;
      3. The contents of the constructor body of the derived class.
Destructors for derived classes

The function of the destructor of a derived class is to perform some necessary cleanup work before the object dies, with no type and no parameters for the destructor. destructors are executed in the opposite order as constructors.

Instance:

#Include<iostream>#Include<time.h>UsingNamespaceStdBase class B1Class b1{PUBLIC:B1 (int i) {cout<<"Constructing B1" <<i<<Endl } ~b1 () {cout<<"Destructing B1" <<Endl }};Base class B2Class b2{PUBLIC:B2 (Int J) {cout<<"Constructing B2" <<j<<Endl } ~b2 () {cout<<"Destructing B2" <<Endl }};Base class B3Class b3{Public:b3 () {cout<<"Constructing B3" <<Endl } ~b3 () {cout<<"Destructing B3" <<Endl }};Derived class C, inherited B2, B1,B3 (declaration order from left to right. B2-&GT;B1-&GT;B3)Class C:Public B2,Public B1,Public b3{PUBLIC:C (int A,int B,int C,int d): B1 (a), memberB2 (d), memberB1 (c), B2 (b) {B1,B2 constructors have parameters, B3 constructors have no arguments//memberb2 (d), memberB1 (c) is the process by which derived classes initialize their own data members, //constructor execution order , the constructor (Declaration order) of the inline member object, base class (declaration order), and the contents of the derived class constructor}PRIVATE:B1 memberB1; B2 memberB2; B3 memberB3;}; int main  () {c obj  (1,2,3 , 4); return 0;} /* output *//*constructing B2 2constructing B1 1constructing B3constructing B1 3constructing B2 4constructing b3destructing b3destructing b2destructing b1destructing b3destructing B1destructing b2*/             
The question of ambiguity

Under single inheritance, the public and protected members of the base class can be accessed directly, just as they are members of a derived class, which is also true for multiple inheritance. However, under multiple inheritance, a derived class can inherit a member of the same name from two or more base classes. In this case, however, direct access is differentiation and will result in compile-time errors.
Example:

#Include<iostream>UsingNamespaceStdClass a{PublicvoidF();};Class b{Publicvoidf ();  void g ();}; class C: public A, public B{public:void g ();  void h ();}; int main  () {C C1; //c1.f (), generating a two semantic question, accessing F () in A, f () of or B? //removes ambiguity C1 by specifying a member name. A::f (); C1. B::f ();}                 

You can eliminate ambiguity by using the member name qualifier, but a better solution is to define a function f () with the same name in Class C, and F () in class C to call A::f() or, as necessary B::f() , to c1.f() invoke C::f() .

When a derived class derives a class from more than one base class, and these base classes have a common base class, there may also be two semantics when accessing the members described in the base class.
Example:

Derived classes b1,b2 inherit the same base class A, derived class C inherits B1, B2Class a{Publicint A;};Class B1:public a{private:int B1;}; class B2: public a{private:int B2;}; class C: public B1, public B2{< Span class= "Hljs-keyword" >public:int f ();  Private:int c;}; int main return 0;}         

c1.a;Both of c1.A::a; these visits are two semantic, c1.B1::a; c1.B2::a; is correct:
The member functions of Class C f() can be eliminated ambiguity by the following definitions:

int C::f(){     retrun B1::a + B2::a; }

For the reason of ambiguity, a class cannot inherit more than one time from the same class directly.

Virtual base class

Naming conflicts are easy to generate when multiple inheritance occurs, even if we carefully name the member variables and member functions in all classes as different names, the naming conflict can still occur, such as the very classic diamond inheritance hierarchy. As shown in the following:

graph TD;    A-->B;    A-->C;    B-->D;    C-->D;

Class A derives from Class B and Class C, and Class D inherits from Class B and Class C, when the member variables and member functions in Class A inherit into Class D into two copies, one from A-->b-->d and the other from A-->c-->d. When d accesses data inherited from a, it becomes impossible to decide which route to pass the data, so there is a virtual base class.

Retaining multiple copies of the same name in a derived class for the indirect base class, although you can store different data in different member variables, in most cases this is superfluous: because preserving multiple member variables not only takes up more storage space, it is also prone to naming conflicts, and there are few such requirements. Using a virtual base class allows you to keep only one member of the indirect base class in the derived class.

Declaring a virtual base class requires only the virtual keyword to precede the inherited method, as in the following example:

#Include<iostream>UsingNamespaceStdClass a{Protectedint A;Public:a (int a): A (a) {}};Class B:VirtualPublic a{Declaring a virtual base classProtectedint b;PUBLIC:B (int A,int b): A (a), B (b) {}};Class C:VirtualPublic a{Declaring a virtual base classProtectedint C;PUBLIC:C (int A,int c): A (a), C (c) {}};Class D:VirtualPublic B,VirtualPublic c{Declaring a virtual base classPrivateint D;Public:d (int A,int B,int C,int d): A (a), B (b), C (A,c), D (d) {}voidDisplay();};void D::d isplay () {cout<<"A=" <<a<<ENDL; cout<< "b=" <<b<< ENDL; cout<< "c=" <<c<< ENDL; cout<< "d=" <<d<< ENDL;} int main  () {(new D (1, 2, 3, 4), display (); return 0;} /* Run Result: a=1b=2c=3d=4*/          

In this case, we used the virtual base class, where there is only one copy of member variable A in the derived class D, so you can access a directly in the display () function without the addition of the class name and the domain resolver.

Initialization of virtual base class
: Note that the constructor for the derived class D differs from the previous usage. in the past, the constructor of a derived class simply had to be responsible for initializing its direct base class, and then its direct base class was responsible for initializing the indirect base class. Now, because the virtual base class has only one copy of the member variable in the derived class, the initialization of the member variable must be given directly by the derived class. If the virtual base class is not initialized directly by the last derived class, and the virtual base class is initialized by a direct derived class of the virtual base class (such as Class B and Class C), it is possible that there is a contradiction between the different initialization parameters of the virtual base class in the constructors of Class B and Class C. So the rule: in the last derived class not only is responsible for its direct base class initialization, but also responsible for the virtual base class initialization.

In the preceding code, the constructor of Class D calls out the constructor a of the virtual base class by initializing the table, and the constructors of Class B and Class C also call the virtual base class constructor A through the initialization table, so that the constructor of the virtual base class is not called 3 times? You don't have to worryabout it. The C + + compilation system only performs calls to the constructor of the virtual base class from the last derived class, ignoring other derived classes of the virtual base class (such as Class B and class C) calls to the virtual base class's constructor, which guarantees that the data members of the virtual base class are not initialized more than once.

Finally, note: in order to ensure that the virtual base class inherits only once in the derived class, it should be declared as a virtual base class in all the direct derived classes of the base class, otherwise multiple inheritance of the base class will still occur.

Assignment compatibility principle

Assignment compatible
Assignment compatibility rules are substituted for objects of a public derived class that can be used anywhere a base class object is needed .

The overrides referred to in the assignment compatibility rule include:

    • The object of a derived class can be assigned to a base class object;
    • An object of a derived class can initialize a reference to a base class;
    • The address of a derived class object can be assigned to a pointer to a base class.
      After the override, the derived class object can be used as an object of the base class, but only members that inherit from the base class are used.

Inheritance of C + + three major features

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.