C++(6)继承

  • Post author:
  • Post category:其他


继承  Inherit

C++中可重用性

父类  基类

继承  派生

子类  派生类

C++通过继承关系,实现了代码的可重用性。

#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;
}

组合是聚合关系

属于是继承关系

public 继承方式没有影响子类成员的访问方式,影响了父类中的成员在子类中的访问方式

父类中               pub      pro           pri

子类public继承  public  protected inaccess

1、继承后全盘接受,除了析构器和构造器。基类会造成派生类的成员冗余,因此积累是需要设计的。

2、派生类有自己的个性,使派生类有了意义。

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;
}

父类中如果有标配,重载或默认,把默认包含进来

子类中可以不用显式的调用父类的构造器

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)
{

}

子类只需对父类负责,不需要对父类的父类负责

类中的子对象  int age, float salary

初始化顺序:父类初始化(父类的父类初始化)、类对象初始化、子类初始化

子类未实现拷贝构造时,会调用父类的拷贝构造器(无论是否实现)

子类一旦实现拷贝构造,则必须显式的调用父类的拷贝构造器

#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;
}

子类中未实现赋值重载时,会调用父类的赋值重载

子类一旦实现赋值重载,不会主动调用父类的赋值重载

子类中会把父类重名的成员shadow

overload 重载:同一作用域,函数名相同,参数列表不同(个数、类型、顺序)  希望发生

shadow  覆盖:父子类中,只要函数名相同即构成shadow   不希望发生

继承方式

成员/继承方式 public protected private
public public protected private
protected protected protected inaccessable
private inaccessable inaccessable inaccessable

类内部的private protected public 影响访问权限

在继承中,private protected public 父类中的成员在子类中的访问权限

1、在子类中  2、在子类对象中

virtual

从诸多父类中提取公因式,把相同的类成员提到祖父类中,分别令父类虚继承祖父类,子类正常继承自父类,此时子类中无冗余信息,访问亦方便。

#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;
}


虚继承

class A: virtual public M

虚基类需要设计和抽象,虚继承是一种继承的扩展

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)
    {}
};



版权声明:本文为jiangyangll原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。