C + + language Learning (10)--Inheritance and derivation

Source: Internet
Author: User
Tags access properties

C + + language Learning (10)--inheritance and derivation, relationship between classes 1, the combination of classes

A combinatorial relationship is the relationship of a whole to a part.
Characteristics of the combined relationship:
A. Use other classes of objects as members of the current class
B, the object of the current class is the same as the life cycle of the Member object
C, the member object is the same as the normal object in usage
The computer class is composed of several other component classes, and when computer is destroyed, the other part objects are destroyed at the same time.

#include <iostream>using namespace Std;class memory{public:memory () {cout << "Memory ()" <&lt ;    Endl    } ~memory () {cout << "~memory ()" << Endl;    }};class Disk{public:disk () {cout << Disk () << Endl;    } ~disk () {cout << "~disk ()" << Endl;    }};class cpu{public:cpu () {cout << "CPU ()" << Endl;    } ~cpu () {cout << "~cpu ()" << Endl;    }};class Mainboard{public:mainboard () {cout << "mainboard ()" << Endl;    } ~mainboard () {cout << "~mainboard ()" << Endl;    }};class computer{Memory Mmem;    Disk MDisk;    CPU mcpu;    Mainboard Mmainboard;public:computer () {cout << "computer ()" << Endl;    } void Power () {cout << power () << Endl;    } void Reset () {cout << "reset ()" << Endl; } ~compUter () {cout << "~computer ()" << Endl;    }};int Main (int argc, char *argv[]) {computer C;    C.reset (); return 0;}
2. Inheritance between classes

An inheritance relationship is a parent-child relationship between classes. The characteristics of the inheritance relationship are as follows:
A, subclasses have all the properties and behaviors of the parent class
B, subclasses are also a special kind of parent
C, subclass objects can be used when the parent class object uses the
D, subclasses can add properties and methods that are not in the parent class
E, subclass objects can be initialized directly to the parent class object
F, subclass objects can be assigned directly to the parent class object
G, inheritance is an important means of code reuse in object-oriented programming

#include <iostream>using namespace std;class Parent{public:    Parent(int i = 0)    {        member = i;    }    void method()    {        cout << "member = " << member << endl;    }private:    int member;};class Child : public Parent{public:    Child(int i = 0, int j = 0):Parent(i)    {        childMember = j;    }    void childMethod()    {        method();        cout << "childMember = "<< childMember << endl;    }private:    int childMember;};int main(int argc, char *argv[]){    Child child(1,2);    child.method();    child.childMethod();    return 0;}
3. Access level selection for class members

The


defines the level of access for a member based on the design requirements of the class, as follows:
A, public decorated members can be accessed externally.
B, protected decorated members can not be accessed externally, but can be accessed by the quilt class. The
C, private decorated members cannot be accessed by external and subclass classes.

#include <iostream>using namespace std;class Parent{public:    Parent(int a = 0, int b = 0, int c = 0)    {       pub = a;       pro = b;       pri = c;    }    void method()    {        cout << "pub = " << pub << endl;        cout << "pro = " << pro << endl;        cout << "pri = " << pri << endl;    }public:    int pub;protected:    int pro;private:    int pri;};class Child : public Parent{public:    Child(int a = 0, int b = 0):Parent(a, b)    {    }    void childMethod()    {        pub = 100;        pro = 200;        //pri = 300;//error,子类不可见    }};int main(int argc, char *argv[]){    Parent parent(1,2);    parent.pub = 1000;    //parent.pro = 2000;//error,外部不可见    //parent.pri = 3000;//error,外部不可见    Child child(1,2);    child.pub = -1000;    //child.pro = -2000;//error,外部不可见    //child.pri = -3000;//error,外部不可见    child.childMethod();    return 0;}
Ii. inheritance 1, Introduction to succession

In C + + programming, software reusability (software reusability) is implemented through the inheritance (inheritance) mechanism. Class, the new class gets the existing attribute from the existing class. The process of generating a new class from an existing class is the derivation of the class. The original class is called a base class or parent class, and the resulting new class is called a derived class or subclass.
Inheritance is an abstraction of the relationship between encapsulated models and a hierarchical classification of different encapsulation models.

2. Definition of derived classes

Declaration of a derived class:

class 派生类名:[继承方式] 基类名{    派生类成员声明;};

If a derived class has multiple base classes at the same time, it is called multiple inheritance, and if the derived class has only one base class, it is called single inheritance.

3. The way of inheriting

The inheritance method specifies how to access the members inherited by the base class. The way of inheritance is public, private, and protected. inheritance specifies the access rights of derived class members and out-of-class objects to members inherited from the base class. The following methods are inherited:
A, public inheritance
The public and protected members of the base class maintain the original Access property in the derived class, and their private members remain private members of the base class.
B, Private inheritance
The public and protected members of the base class are private members in the derived class, and their private members are still private members of the base class.
C, protection of inheritance
The public and protected members of the base class are protected members in the derived class, and their private members are still private members of the base class.
The access levels for parent members under different inheritance methods are as follows:

Access properties of inherited members = max{inheritance, access properties of parent class members}

4. Default inheritance Mode

When you define a derived class by using the Class keyword, the default inheritance is private.
When you define a derived class by using the struct keyword, the default inheritance is public.
In C + + projects, public inheritance is usually used only.

5. Examples of different ways of inheriting
#include <iostream>using namespace Std;class parent{public:parent (int a = 0, int b = 0, int c = 0) {PU       b = A;       Pro = B;    pri = c; }public:int pub;protected:int pro;private:int pri;}; Class Childa:public Parent{public:childa (int a = 0, int b = 0):P arent (A, b) {} void print () {Co        UT << "pub =" << pub << Endl;        cout << "pro =" << pro << Endl; cout << "pri =" << pri << endl;//error, private member not visible}};class childb:protected parent{public:child b (int a = 0, int b = 0):P arent (A, b) {} void print () {cout << pub = << pub << en        dl        cout << "pro =" << pro << Endl; cout << "pri =" << pri << endl;//error, private member not visible}};class childc:private PARENT{PUBLIC:CHILDC ( int a = 0, int b = 0):P arent (A, b) {} void print () {cout << "pub =" <<        Pub << Endl;        cout << "pro =" << pro << Endl; cout << "pri =" << pri << endl;//error, private member invisible}};//default inheritance way class Childd:parent{public:childd (int a = 0, int b = 0):P arent (A, b) {} void print () {cout << pub = << pub << end        L        cout << "pro =" << pro << Endl; cout << "pri =" << pri << endl;//error, private member not visible}};int main (int argc, char *argv[]) {Childa chil    Da (1000,2000);    childa.pub = 0;    Childa.pro = 2000;//error, external invisible//childa.pri = 3000;//error, external invisible childa.print ();    Childb childb (1001,2001); Childb.pub = 1001;//error, externally invisible//childb.pro = 2001;//error, externally invisible//childb.pri = 3001;//error, externally invisible Childb.prin    T ();    CHILDC CHILDC (1002,2002); Childc.pub = 1002;//error, externally invisible//childc.pro = 2002;//error, externally invisible//childc.pri = 3002;//error, externally invisible Childc.prin    T ();    Childd childd (1003,2003); CHildd.pub = 1003;//error, externally invisible//childd.pro = 2003;//error, externally invisible//childd.pri = 3003;//error, externally invisible childd.print ()    ; return 0;}
Iii. Introduction to derived classes 1, derived classes

A member of a derived class contains two parts, one that inherits from a base class, and one that is its own added member. Members that inherit from the base class exhibit their commonality, and the new members embody their individuality.
The initialization of a member inherited from a base class in a derived class is either done by the constructor of the base class, and then the new member in the derived class is initialized in the constructor of the derived class. Derived classes do not inherit the constructors and destructors of the base class.

2. Constructors for derived classes

The constructor syntax for a derived class is as follows:

派生类名::派生类名(参数总表):基类名(参数表),内嵌子对象(参数表){    派生类新增成员的初始化语句; //也可出现在参数列表中}

The subclass constructor must initialize the inherited member, either directly through the initialization list or assignment, or by calling the parent class constructor.
How the parent class constructor is called in the subclass:
A, default invocation, for parameterless constructors and constructors that use default parameters
B, show call, apply to all parent class constructors, call through initialization list

  #include <iostream> #include <string>using namespace Std;class parent{public:parent () {    cout << "Parent ()" << Endl;    } parent (string s) {cout << "Parent (string s):" << s << endl;    } ~parent () {cout << "~parent ()" << Endl;  }};class child:public parent{public://Implicitly calls the parameterless constructor of the parent class or the default argument constructor child () {cout << ' child ' () <<    Endl        }//shows the call to the parent class constructor, if the call is not displayed, the default call//parent class of the parameterless constructor or the default argument constructor child (string s):P arent (s) {name = S;    cout << "Child ():" << s << endl;    } ~child () {cout << "~child ():" << name << Endl; }private:string name;};    int main (int argc, char *argv[]) {Child child1 ("Bauer"); Output://Parent (string s): Bauer//Child (): Bauer//~child (): Bauer//~parent () return 0;}  

The order in which the

Constructors are called is not in the order in which they are called in the initialization list, but in the order in which the member variables are declared in the class. If there is no default constructor (no parameter) in the base class, you must display the call base class constructor in the constructor of the derived class to initialize the base class member.
derived class objects are created with the following order of invocation:
A, call the base class constructor, the order in which the call order is declared when the base class is inherited (left to right),
B, the constructor that invokes the member variable, the order in which the call order is declared in the class by the member variable;
C, Call the constructor of the derived class itself. In the
subclass constructor, either the constructor (pass parameter) of the calling parent class is displayed, or an implicit invocation. When an implicit call occurs, the parent class has a parameterless constructor or a default parameter function that can contain a parameterless constructor. The subclass constructor must initialize the inherited member, either by initializing the list or by assigning a method to initialize it, or by calling the parent class constructor. The
Subclass object is created when the constructor is called in the following order:
A, call the constructor of the parent class
B, call the constructor of the member variable
C, call the constructor of the class itself

#include <iostream>using namespace Std;class parent{public:parent () {cout << "Parent ()" <&lt ;    Endl    } parent (string s) {cout << "Parent (string s):" << s << endl;    } ~parent () {cout << "~parent ()" << Endl;        }};class member{public:member (int i = 0) {this->i = i;    cout << "Member (int i = 0) i =" << i << Endl;    } ~member () {cout << "~member () i =" << i << Endl; }private:int i;}; Class Child:public Parent{public://Implicitly calls the parameterless constructor of the parent class or the default argument constructor child () {cout << ' child () ' << en    dl         }//shows the call to the parent class constructor, if the call is not displayed, the default call//parent class of the parameterless constructor or the default argument constructor child (string s, int i):P arent (s), member (i) {name = S;    cout << "Child ():" << s << endl;    } ~child () {cout << "~child ():" << name << Endl;    }private:string name; Member Member;};int Main (int argc, char *argv[]) {child Childa ("Bauer", 10); Output://Parent (string s): Bauer//Member (int i = 0) i = ten//Child (): Bauer//~child (): Bauer//~ Member () i = ten//~parent () return 0;}
3. Copy constructors for derived classes

The definition of a derived class copy constructor is as follows:

派生类::派生类(const 派生类& another):基类(another),派生类新成员(another.新成员){ }

The default copy constructor in a derived class invokes a default or self-implementing copy constructor in the parent class, and if the copy constructor is self-implemented in a derived class, the copy constructor that invokes the parent class must be displayed.

#include <iostream> #include <string>using namespace Std;class student{public:student (string Sn,int N,char        s) {name = SN;        num = n;       sex = s;    cout << "Student (string sn,int n,char s)" << Endl;        } Student (const student& another) {name = Another.name;        num = Another.num;    sex = Another.sex;    } ~student () {cout << "~student ()" << Endl;        } void Print () {cout << name << Endl;        cout << num << endl;    cout << sex << endl;    }private:string name;    int num; char sex;}; Class Graduate:public Student{public:graduate (String sn,int in,char cs,int FS): Student (SN, in, CS) {Salar        y = FS;    cout << "Graduate (string Sn,int In,char cs,float fs)" << Endl;    } ~graduate () {cout << "~graduate ()" << Endl; } graduate (const graduate& Another): Student (another) {salary = Another.salary;        } void Display () {print ();    cout<<salary<<endl; }private:int salary;};    int main (int argc, char *argv[]) {graduate S ("Bauer", 1001, ' M ', 8000);    S.display ();    Graduate g = s;    G.display (); return 0;}
4. Assignment operator overloading of derived classes

The assignment operator overload function for a derived class is defined as follows:

子类& 子类::operator=(const 子类& another){    if(this != &another){  父类::operator =(another); // 调用父类的赋值运算符重载    this->salary = another.salary;//子类成员初始化}        return * this;}

If you do not implement an assignment operator function for a derived class, the C + + compiler provides a default assignment operator overload function that invokes the assignment operator overload function of the parent class (the default assignment operator overload function provided by the compiler or an assignment operator overload function provided by the developer).

#include <iostream> #include <string>using namespace Std;class student{public:student (string Sn,int N,char        s) {name = SN;        num = n;       sex = s;    cout << "Student (string sn,int n,char s)" << Endl;        } Student (const student& another) {name = Another.name;        num = Another.num;    sex = Another.sex; } student& operator = (const student& Another) {if (This! = &another) {name =            Another.name;            num = Another.num;        sex = Another.sex;    } return *this;    } ~student () {cout << "~student ()" << Endl;        } void Print () {cout << name << Endl;        cout << num << endl;    cout << sex << endl;    }private:string name;    int num; char sex;}; Class Graduate:public Student{public:graduate (String sn,int in,char cs,int FS): Student (SN, in, CS) {sAlary = FS;    cout << "Graduate (string Sn,int In,char cs,float fs)" << Endl;    } ~graduate () {cout << "~graduate ()" << Endl;    } graduate (const graduate& Another): Student (another) {salary = Another.salary;        } void Display () {print ();    cout<<salary<<endl; }private:int salary;};    int main (int argc, char *argv[]) {graduate S ("Bauer", 1001, ' M ', 8000);    cout << Endl;    S.display ();    cout << Endl;    Graduate g ("Lee", 1002, ' F ', 9000);    cout << Endl;    G.display ();    cout << Endl;    g = s;    G.display ();    cout << Endl; return 0;}

Derived classes If you implement an assignment operator overload function, you need to call the assignment operator overload function of the parent class within the assignment operator overload function.

#include <iostream> #include <string>using namespace Std;class student{public:student (string Sn,int N,char        s) {name = SN;        num = n;       sex = s;    cout << "Student (string sn,int n,char s)" << Endl;        } Student (const student& another) {name = Another.name;        num = Another.num;    sex = Another.sex; } student& operator = (const student& Another) {if (This! = &another) {name =            Another.name;            num = Another.num;        sex = Another.sex;    } return *this;    } ~student () {cout << "~student ()" << Endl;        } void Print () {cout << name << Endl;        cout << num << endl;    cout << sex << endl;    }private:string name;    int num; char sex;}; Class Graduate:public Student{public:graduate (String sn,int in,char cs,int FS): Student (SN, in, CS) {sAlary = FS;    cout << "Graduate (string Sn,int In,char cs,float fs)" << Endl;    } ~graduate () {cout << "~graduate ()" << Endl;    } graduate (const graduate& Another): Student (another) {salary = Another.salary; } graduate& operator = (const graduate& Another) {if (This! = &another) {stude            Nt::operator = (another);        salary = Another.salary;    } return *this;        } void Display () {print ();    cout<<salary<<endl; }private:int salary;};    int main (int argc, char *argv[]) {graduate S ("Bauer", 1001, ' M ', 8000);    cout << Endl;    S.display ();    cout << Endl;    Graduate g ("Lee", 1002, ' F ', 9000);    cout << Endl;    G.display ();    cout << Endl;    g = s;    G.display ();    cout << Endl; return 0;}
5. Destructors for derived classes

The function of the destructor of a derived class is to perform some necessary cleanup work before the object is destroyed, with no type or parameters for the destructor. Destructors are called in the opposite order of constructors.
Destructors have only one, no overloads, no implicit parameters.
When the subclass object is destroyed, the destructor is called in the following order:
A. Call the destructor of the class itself
B. Destructors that call member variables
C. Call the destructor of the parent class
Iv. overriding the same name as the parent class and child class
When a subclass defines a member of the same name in a parent class, an overwrite occurs with the following rule:
A, subclasses can define members of the same name (member variables and member functions) in the parent class
B, a member in a subclass hides a member of the same name in the parent class
C, a member of the same name in the parent class still exists in the child class
D accessing members of the same name in the parent class through scope accessors
If more than one base class of a derived class has a member with the same name, and the derived class is new to a member with the same name as the base class, the derived class member Shadow (hides) the member of the same name for all base classes, requiring the calling method of the scope to invoke the same member of the base class.

#include <iostream>using namespace std;class Parent{public:    int m_count;    void print()    {        cout << &m_count << endl;    }};class Child : public Parent{public:    int m_count;    void print()    {        cout << &(Parent::m_count) << endl;        cout << &m_count << endl;    }};int main(int argc, char *argv[]){    Parent p;    p.print();    cout << &p.m_count << endl;    Child child;    child.print();    //子类对象的父类同名成员变量访问    cout << &child.Parent::m_count <<endl;    //子类对象的父类同名成员函数访问    child.Parent::print();    cout << &child.m_count << endl;    return 0;}

Function overloading occurs in the same scope, where a function with the same name as the parent class and subclass does not constitute a function overload, is overridden by the same name, and the subclass hides a member of the same name in the parent class.
A subclass can define a member of the same name in a parent class, and a member in the child class hides a member of the same name in the parent class, and a member of the same name in the parent class still exists in the subclass, through the scope resolution: Access the member of the same name in the parent class.
A member function in a subclass hides a member function with the same name in the parent class, which cannot overload a member function with the same name in the parent class, and use a scope-resolved character to access a member function of the same name in the parent class.

#include <iostream>using namespace std;class Parent{public:    int mi;    void add(int i)    {        mi += i;    }    void add(int a, int b)    {        mi += (a + b);    }};class Child : public Parent{public:    int mi;    void add(int x, int y, int z)    {        mi += (x + y + z);    }};int main(int argc, char *argv[]){    Parent p;    p.add(1);    p.add(1,2);    Child child;    child.add(1,2,3);    //child.add(1);//error    child.Parent::add(1);    //child.add(1,2);//error    child.Parent::add(1,2);    return 0;}
Five, assignment compatibility principle 1, Assignment compatibility principle Introduction

The assignment compatibility principle refers to child class objects that can be used as parent objects.
The characteristics of the assignment compatibility principle are as follows:
A, subclass object can be directly assigned to the parent class object
B, subclass object can initialize parent class object directly
C, the parent class pointer can point directly to the subclass object
D, the parent class reference can directly refer to the Child class object
When a parent class pointer is used to point to a subclass object, the parent class references a child class object for reference, the subclass object is degraded to the parent class object, only the members defined in the parent class can be accessed, and therefore the members of the same name overridden by the quilt class are accessed directly.

#include <iostream>using namespace std;class Parent{public:    int mi;    void add(int i)    {        mi += i;    }    void add(int a, int b)    {        mi += (a + b);    }};class Child : public Parent{public:    int mi;    void add(int x, int y, int z)    {        mi += (x + y + z);    }};int main(int argc, char *argv[]){    Child child;    Parent p = child;    p.add(1);    p.add(1,2);    Parent& rp = child;    rp.add(1);    rp.add(1,2);    //rp.add(1,2,3);//error    Parent* pp = &child;    pp->add(1);    pp->add(1,2);    //pp->add(1,2,3);//error    return 0;}
2. Function rewriting

In a subclass, a member function that already exists in the parent class is redefined, called a function rewrite.
A function rewrite is a special case of overwriting with the same name.

#include <iostream>using namespace std;class Parent{public:    int mi;    void add(int i)    {        mi += i;    }    void add(int a, int b)    {        mi += (a + b);    }    void print()    {        cout << "Parent" << endl;    }};class Child : public Parent{public:    int mi;    //函数重写    void add(int x, int y)    {        mi += (x + y);    }    //函数重写    void print()    {        cout << "Child" << endl;    }};int main(int argc, char *argv[]){    Child child;    Parent p = child;    p.add(1);    p.add(1,2);    Parent& rp = child;    rp.add(1);    rp.add(1,2);    rp.print();//Parent    Parent* pp = &child;    pp->add(1);    pp->add(1,2);    pp->print();//Parent    return 0;}

C + + is a statically compiled language that, during compilation, the C + + compiler can only judge the object to which it is pointing based on the type of pointer. Based on the assignment compatibility principle, the C + + compiler considers the parent pointer to be the parent class object, and the parent class reference is a reference to the parent class object, so the compilation result can only be called a function with the same name as defined in the parent class.

C + + language Learning (10)--Inheritance and derivation

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.