C++(6) inheritance

Inherit Inherit

Reusability in C++

parent class base class

Inheritance Derived

subclass derived class

C++ achieves code reusability through inheritance.

#include <iostream>

using namespace std;

class Human    //父类  共性
{
public:
    void eat(string food)
    {
        cout<<"i am eating"<<food<<endl;
    }
};

//public 继承方式
class Teacher:public Human  //  子类在父类的基础上增加了新的功能,体现的是个性
{
//访问权限
public:
    void tech(string course)
    {
        cout<<"i am a teacher teach "<<course<<endl;
    }
};

class Student:public Human
{
public:
    void study(string course)
    {
        cout<<"i am a student learning "<<course<<endl;
    }
};

int main()
{
    Teacher t;
    t.tech("ttttt");

    Student s;
    s.eat("aaa");
    s.study("c++");

    return 0;
}

Composition is an aggregation relationship

belongs to inheritance relationship

The public inheritance method does not affect the access method of subclass members, but affects the access method of members in the parent class in the subclass

pub pro pri in the parent class

Subclass public inherits public protected inaccess

 1. Accept everything after inheritance, except for destructors and constructors. The base class will cause redundant members of the derived class, so accumulation needs to be designed.

2. The derived class has its own personality, which makes the derived class meaningful.

student.h

#ifndef STUDENT_H
#define STUDENT_H

#include <iostream>
using namespace std;

class Student
{
public:
    Student(string sn, int ia, float fs)
    {
    }

    void dis();    

private:
    string name;
    int age;
    float score;
};

#endif  //STUDENT_H

student.cpp

#include "student.h"
#include <iostream>

Student::Student(string sn, int ia, float fs)
    :name(sn),age(ia),score(fs)
{

}

void Student::dis()
{
    cout<<"name: "<<name<<endl;
    cout<<"age: "<<age<<endl;
    cout<<"score: "<<score<<endl;
}

main.cpp

#include <iostream>
#include "student.h"
#include "gradient.h"
#include "doctor.h"

using namespace std;

int main()
{
    Student s("aa", 30, 100);
    s.dis();
    cout<<"----------"<<endl;

    Graduate g("ggg", 50, 90, 1000);
    g.print();

    Doctor d("ddd", 23, 200, 5000, "doc");
    d.dump();

    return 0;
}

Graduate.h

#ifndef GRADUATE_H
#define GRADUATE_H
#include "student.h"

class Graduate:public Student
{
public:
    Graduate(string sn, int ia, float fs, double ds);

    void print();
private:
    double salary;
};

#endif  //GRADUATE_H

gradient.cpp 

#include "gradient.h"

Gradient::Gradient(string sn, int ia, float fs, double ds)
    :Student(sn, ia, fs),salary(ds)
{
    //inaccess
    // name = sn;
    // age = ia;
    // score = fs;
}

void Gradient::print()
{
    dis();  // name age score 不可见,dis()可用
    cout<<"salary: "<<salary<<endl;
}

If there is standard configuration, overload or default in the parent class, include the default

Subclasses do not need to explicitly call the constructor of the parent class

Doctor.h

#ifndef DOCTOR_H
#define DOCTOR_H
#include "gradient.h"

class Doctor:public Gradient
{
public:
    Doctor(string sn, int ia, float fs, double ds, string st);

    void dump()
    {
        print();
        cout<<"title: "<<title<<endl;
    }

private:
    string title;
};

#endif  //DOCTOR_H

doctor.cpp 

#include "doctor.h"

Doctor::Doctor(string sn, int ia, float fs, double ds, string st)
    :Gradient(sn,ia,fs,ds),title(st)
{

}

The subclass only needs to be responsible for the parent class, not the parent class of the parent class

Subobjects in class int age, float salary

Initialization order: parent class initialization (parent class initialization of parent class), class object initialization, subclass initialization

When the subclass does not implement copy construction, the copy constructor of the parent class will be called (whether it is implemented or not)

Once the subclass implements copy construction, it must explicitly call the copy constructor of the parent class

#ifndef STUDENT_H
#define STUDENT_H

class Student
{
public:
    Student(string sn, int ia, float fs):
    void dis();
    Student(const Student& another);  // 构造器
    Student & operator = (const Student & another);

private:
    string name;
    int age;
    float score;
};

#endif
#include "student.h"
#include <iostream>

using namespace std;

Student::Student(string sn, int ia, float fs)
    :name(sn),age(ia),score(fs)
{
    
}

void Student::dis()
{
    cout<<"name: "<<name<<endl;
    cout<<"age: "<<age<<endl;
    cout<<"score: "<<score<<endl;
}

//定义构造器
Student::Student(const Student& another)
{
    this->name = another.name;
    this->age = another.age;
    this->score= another.score;
}

Student & Student::operator = (const Student & another)
{
    if(this == &another)
        return *this;

    this->name = another.name;
    this->age = another.age;
    this->score = another.score;

    return *this;
}
#ifndef GRADIENT_H
#define GRADIENT_H
#include "student.h"

class Gradient
{
public:
    Gradient(string sn, int ia, float fs, double ds);
    void print();
    Gradient(const & another);  // 构造器
    Gradient & another = (const Gradient & another);
private:
    double salary;
};

#endif
#include "gradient.h"
#include <iostream>

using namespace std;

Gradient::Gradient(string sn, int ia, float fs, double ds)
    :Student(sn, ia, fs),salary(ds)
{
    
}

void Gradient::print()
{
    dis();
    cout<<"salary: "<<salary<<endl;
}

Gradient::Gradient(const Gradient& another)
    :Student(another),salary(another.salary)
{
    // Student(another);  // 赋值兼容(子类对象(引用或指针),可以赋值给父类(引用或指针))
    // this->salary = another.salary;
}

Gradient & Gradient::operator = (const Gradient & another)
{

}


#include <iostream>
#include "student.h"
#include "gradient.h"

using namespace std;

int main()
{
    Student s("aa", 200, 100);
    s.dis();

    cout<<"---------"<<endl;

    Gradinet g("gg", 100, 500);
    g.print();

    return 0;
}

When the assignment overload is not implemented in the subclass, the assignment overload of the parent class will be called

Once the subclass implements assignment overloading, it will not actively call the assignment overloading of the parent class

In the subclass, the member with the same name as the parent class will be shadowed

overload Overloading: the same scope, the same function name, different parameter lists (number, type, order) hope to happen

Shadow coverage: In the parent and child classes, as long as the function names are the same, it constitutes a shadow, which is not expected to happen

Inheritance

member/inheritance public protected private
public public protected private
protected protected protected inaccessable
private inaccessable inaccessable inaccessable

The private protected public inside the class affects access rights

In inheritance, private protected public access rights of members in the parent class in the subclass

1. In a subclass 2. In a subclass object   

virtual 

Extract the common factor from many parent classes, mention the same class members to the grandparent class, respectively make the parent class virtual inherit the grandparent class, and the subclass normally inherit from the parent class. At this time, there is no redundant information in the subclass, and access is also possible. convenient.

#include <iostream>

using namespace std;

class M
{
public:
    M(int m):a(m){}
protected:
    int a;
};

class A:virtual public M
{
public:
    A(int i):M(i){}
};

class B:virtual public M
{
public:
    B(int j):M(j){}
};

class C:public A, public B
{
public:
    C(int m):A(m), B(m), M(m){}
    void func()
    {
        cout<<a<<endl;
    }
};

int main()
{
    C c(100);
    c.func();
    return 0;
}

virtual inheritance

class A: virtual public M

Virtual base classes require design and abstraction, and virtual inheritance is an extension of inheritance

class A
{
    A(int i)
    {}
};

class B:virtual public A
{
    B(int n):A(n){}
};

class C:virtual public A
{
    C(int n):A(n){}
};

class D:public B, public C
{
    D(int n)
        :A(n), B(n), C(n)
    {}
};

Guess you like

Origin blog.csdn.net/jiangyangll/article/details/132326744