菜鸟资源网站全面焕新升级啦!全新的界面设计,简洁而不失雅致,让您一目了然,轻松上手。我们还对资源分类进行了细致梳理,确保各类资源条理清晰,便于您按需筛选与查找。 立即查看

第十二章丨C++编程宝典:快速上手、深入进阶、挑战高级技巧,助你成为编程达人

第十二章丨C++编程宝典:快速上手、深入进阶、挑战高级技巧,助你成为编程达人

在面向对象编程中,继承和派生是两个重要的概念,它们允许程序员从已有的类创建新的类。这些概念在不同的编程语言中有不同的实现方式,但基本的思路是相似的。 1.继承 (Inheritance): 继承是从已有的类创建一个新类。新类(子类)继承了父...

当前版本

软件大小

软件语言

是否破解

在面向对象编程中,继承和派生是两个重要的概念,它们允许程序员从已有的类创建新的类。这些概念在不同的编程语言中有不同的实现方式,但基本的思路是相似的。

1.继承 (Inheritance): 继承是从已有的类创建一个新类。新类(子类)继承了父类(基类)的所有属性和方法。子类可以重写父类的某些方法,或者添加新的属性和方法。继承是面向对象编程中的一个基本特性,它允许代码的重用和模块化。
例如,如果我们有一个“动物”类,我们可以从这个类派生出“狗”类和“猫”类。在这种情况下,“狗”类和“猫”类继承了“动物”类的所有属性和方法。

  1. 派生 (Derivation): 在某些语境中,“派生”和“继承”是同义词。然而,在其他语境中,“派生”可能指的是一个更具体的概念,即从一个基类派生出一个或多个子类。在这种情况下,“派生”与“继承”略有不同,因为它更强调从一个基类创建多个子类的过程。

总的来说,无论使用“继承”还是“派生”,都是为了创建更具体的类,这些类继承并扩展了更一般的类的属性和方法。在实现这些概念时,需要考虑到代码的重用、封装和多态性等面向对象编程的基本原则。

第十二章丨C++编程宝典:快速上手、深入进阶、挑战高级技巧,助你成为编程达人

上一章我们讲了运算符重载(Operator Overloading)下面继续讲解继承与派生(Inherit&&Derive)

7. 继承与派生(Inherit&&Derive)

7.1. 引入

在 C++中可重用性(software reusability)是通过继承(inheritance)这一机制来实现的。如果没有掌握继承性,就没有掌握类与对象的精华。

引例

#include <iostream>
using namespace std;
class Student
{
public:
    void dis()
    {
        cout<<name<<endl;
        cout<<age<<endl;
    }
    string name;
    int age;
    };
//重写:
//class Student2
//{
//public:
//    void dis()
//    {
//        cout<<name<<endl;
//        cout<<age<<endl;
//        cout<<sex<<endl;
//        cout<<score<<endl;
//    }
//private:
//    string name;
//    int age;
//    char sex;
//    float score;
//};
//继承:
class Student2:public Student
{
public:
    Student2(string n,int a,char s,float f)
    {
        name = n;
        age = a;
        sex = s;
        score = f;
    }
    void dis()
    {
        Student::dis();
        cout<<sex<<endl;
        cout<<score<<endl;
    }
    char sex;
    float score;
};
int main()
{
        Student2 s("wangwu",23,'s',200);
        s.dis();
        return 0;
}

7.2. 定义

类的继承,是新的类从已有类那里得到已有的特性。或从已有类产生新类的过程就是类的派生。原有的类称为基类或父类,产生的新类称为派生类或子类。

派生与继承,是同一种意义两种称谓。

isA 的关系。

7.3. 继承

7.3.1. 语法

派生类的声明:

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

一个派生类可以同时有多个基类,这种情况称为多重继承,派生类只有一个基类,称为单继承。下面从单继承讲起。

7.3.2. 继承方式

继承方式规定了如何访问基类继承的成员。继承方式有 public, private, protected。继承方式指定了派生类成员以及类外对象对于从基类继承来的成员的访问权限

简单讲:

公有继承:基类的公有成员和保护成员在派生类中保持原有访问属性,其私有成员仍为基类的私有成员。

私有继承:基类的公有成员和保护成员在派生类中成了私有成员,其私有成 员仍为基类的私有成员。

保护继承:基类的公有成员和保护成员在派生类中成了保护成员,其私有成 员仍为基类的私有成员。

pretected 对于外界访问属性来说,等同于私有,但可以派生类中可见。

#include <iostream>
using namespace std;
class Base
{
public:
    int pub;
protected:
    int pro;
private:
    int pri;
};
class Drive:public Base
{
public:
    void func()
    {
        pub = 10;
        pro = 100;
//        pri = 1000;
    }
};
//
int main()
{
    Base b;
    b.pub = 10;
//    b.pro = 100;
//    b.pri = 1000;
    return 0;
}

7.3.3. 派生类的组成

派生类中的成员,包含两大部分,一类是从基类继承过来的,一类是自己增加的成员。从基类继承过过来的表现其共性,而新增的成员体现了其个性。

第十二章丨C++编程宝典:快速上手、深入进阶、挑战高级技巧,助你成为编程达人

几点说明:

1,全盘接收,除了构造器与析构器。基类有可能会造成派生类的成员冗余,所以说基类是需设计的。

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

7.4. 派生类的构造

派生类中由基类继承而来的成员的初始化工作还是由基类的构造函数完成,然后派生

类中新增的成员在派生类的构造函数中初始化。

7.4.1. 派生类构造函数的语法:

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

注:

 构造函数的初始化顺序并不以上面的顺序进行,而是根据声明的顺序初始化。

 如果基类中没有默认构造函数(无参),那么在派生类的构造函数中必须显示调用基

类构造函数,以初始化基类成员。

 派生类构造函数执行的次序:

基类-->成员-->子类

a 调用基类构造函数,调用顺序按照它们被继承时声明的顺序(从左到右);

b 调用内嵌成员对象的构造函数,调用顺序按照它们在类中声明的顺序;

c 派生类的构造函数体中的内容。

7.4.2. 代码实现

 祖父类

student.h

class Student
{
public:
    Student(string sn,int n,char s);
    ~Student();
    void dis();
private:
    string name;
    int num;
    char sex;
};

student.cpp

Student::Student(string sn, int n, char s)
    :name(sn),num(n),sex(s)
{
}
Student::~Student()
{
}
void Student:: dis()
{
    cout<<name<<endl;
    cout<<num<<endl;
    cout<<sex<<endl;
}

 父类
graduate.h

class Graduate:public Student
{
public:
    Graduate(string sn,int in,char cs,float fs);
    ~Graduate();
    void dump()
    {
    dis();
        cout<<salary<<endl;
    }
private:
    float salary;
};

graduate.cpp

Graduate::Graduate(string sn, int in, char cs, float fs)
:Student(sn,in,cs),salary(fs)
{
}
Graduate::~Graduate()
{
}

 类成员

birthday.h

class Birthday
{
public:
    Birthday(int y,int m,int d);
    ~Birthday();
    void print();
private:
    int year;
    int month;
    int day;
};

birthday.cpp

Birthday::Birthday(int y, int m, int d)
:year(y),month(m),day(d)
{
}
Birthday::~Birthday()
{
}
void Birthday::print()
{
    cout<<year<<month<<day<<endl;
}

 子类

doctor.h

class Doctor:public Graduate
{
public:
    Doctor(string sn,int in,char cs,float fs,string st,int iy,int im,in
t id);
    ~Doctor();
    void disdump();
private:
    string title;
    Birthday birth; //类中声明的类对象
};

doctor.cpp

Doctor::Doctor(string sn, int in, char cs, float fs, string st, int iy,
int im, int id)
    :Graduate(sn,in,cs,fs),birth(iy,im,id),title(st)
{
}
Doctor::~Doctor()
{
}
void Doctor::disdump()
{
    dump();
    cout<<title<<endl;
    birth.print();
}

 测试代码

int main()
{
    Student s("zhaosi",2001,'m');
    s.dis();
    cout<<"----------------"<<endl;
    Graduate g("liuneng",2001,'x',2000);
    g.dump();
    cout<<"----------------"<<endl;
    Doctor d("qiuxiang",2001,'y',3000,"doctor",2001,8,16);
    d.disdump();
    return 0;
}

7.4.3. 结论

子类构造器中,要么显示的调用父类的构造器(传参),要么隐式的调用。发生隐式调用时,父类要有无参构造器或是可以包含无参构造器的默认参数函数。子类对象亦然

7.5. 派生类的拷贝构造

7.5.1. 格式

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

7.5.2. 代码

 父类

student.h

class Student
{
public:
    Student(string sn,int n,char s);
    Student(const Student & another);
    ~Student();
    void dis();
private:
    string name;
    int num;
    char sex;
};

student.cpp

Student::Student(string sn, int n, char s)
    :name(sn),num(n),sex(s)
{
}
Student::~Student()
{
}
void Student:: dis()
{
    cout<<name<<endl;
    cout<<num<<endl;
    cout<<sex<<endl;
}
Student::Student(const Student & another)
{
    name = another.name;
    num = another.num;
    sex = another.sex;
}

 子类

graduate.h

class Graduate:public Student
{
public:
    Graduate(string sn,int in,char cs,float fs);
    ~Graduate();
    Graduate(const Graduate & another);
    void dump()
    {
        dis();
        cout<<salary<<endl;
    }
private:
    float salary;
};

graduate.cpp

Graduate::Graduate(string sn, int in, char cs, float fs)
    :Student(sn,in,cs),salary(fs)
{
}
Graduate::~Graduate()
{
}
Graduate::Graduate(const Graduate & another)
    :Student(another),salary(another.salary)
{
}

 测试代码

int main()
{
    Graduate g("liuneng",2001,'x',2000);
    g.dump();
    Graduate gg = g;
    gg.dump();
    return 0;
}

7.5.3. 结论:

派生类中的默认拷贝构造器会调用父类中默认或自实现拷贝构造器,若派生类中自实现拷贝构造器,则必须显示的调用父类的拷贝构造器。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

常见问题

  • 如何安装和激活?

    每款软件会附带有安装教程,您打开安装包一目了然

  • 程序是否已损坏?文件损坏?还是其他错误?

    有错误问题,请您参考:https://www.xxx.com/error

  • 如何更新?正式激活后会发生什么情况?

    除非安装说明中另有说明,否则官方更新可能会导致无法激活。 要从本网站更新软件,您需要在此处下载此软件的新版本(如果可用),并将其安装在计算机上安装的版本之上(替换)。在这种情况下,您将保存此软件的激活和设置。

  • 如何下载?链接不起作用?

    我们使用百度网盘,132云盘和微软网盘,除了百度网盘,其他两款不限速,如果链接失效,请您联系客服处理

  • 已发布更新。我什么时候升级我的版本?

    所有软件如有更新,我们第一时间推送,视自己情况更新使用

  • 如何更改语言?

    打开“系统偏好设置”->“通用>语言和地区”->应用程序-“+”。 选择应用和语言。此方法适用于大多数应用程序。 Adobe 产品中的语言通常是在产品本身的安装阶段选择的。 游戏中的语言通常会在游戏本身的设置中发生变化。

  • 如何删除软件?

    有很多选择。最简单的方法是使用特殊的实用程序来卸载应用程序,例如App Cleaner Uninstaller 要删除 Adobe 产品,请使用 Creative Cloud Cleaner Tool

  • 需要远程帮助吗?

    网站已开通永久会员的可享受免费远程,如果非永久会员,远程安装另外收费

给TA打赏
共{{data.count}}人
人已打赏
技术教程

第十一章丨C++编程宝典:快速上手、深入进阶、挑战高级技巧,助你成为编程达人

2024-2-1 9:49:13

技术教程

第十三章丨C++编程宝典:快速上手、深入进阶、挑战高级技巧,助你成为编程达人

2024-2-2 10:39:28

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧