《C++多线程编程实战》——1.6 解释继承、重载和覆盖

简介:

本节书摘来自异步社区出版社《C++多线程编程实战》一书中的第1章,第1.6节,作者: 【黑山共和国】Milos Ljumovic(米洛斯 留莫维奇),更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.6 解释继承、重载和覆盖

继承是OOP中非常重要的特性。继承至少关系到两个类(或更多类):如果B类是某一种A类,那么B类的对象就拥有与A类对象相同的属性。除此之外,B类也可以实现新的方法和属性,以代替A类相应的方法和属性。

准备就绪
确定安装并运行了Visual Studio。

操作步骤
现在,执行以下步骤来修改前面的示例。

1.创建一个默认控制台应用程序,命名为InheritanceTest

2.打开InheritanceTest.cpp文件,输入下面的代码:

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

using namespace std;

class CPerson
{
public:
   CPerson(int iAge, char* sName)
   {
     this->iAge = iAge;
     strcpy_s(this->sName, 32, sName);
   }
   virtual char* WhoAmI()
   {
     return "I am a person";
   }
private:
   int iAge;
   char sName[32];
};

class CWorker : public CPerson
{
public:
   CWorker(int iAge, char* sName, char* sEmploymentStatus)
     : CPerson(iAge, sName)
   {
     strcpy_s(this->sEmploymentStatus, 32, sEmploymentStatus);
   }
   virtual char* WhoAmI()
   {
     return "I am a worker";
   }
private:
   char sEmploymentStatus[32];
};

class CStudent : public CPerson
{
public:
   CStudent(int iAge, char* sName, char* sStudentIdentityCard)
     : CPerson(iAge, sName)
   {
     strcpy_s(this->sStudentIdentityCard, 32, sStudentIdentityCard);
   }
   virtual char* WhoAmI()
   {
     return "I am a student";
   }
private:
   char sStudentIdentityCard[32];
};

int _tmain(int argc, TCHAR* argv[])
{
   CPerson cPerson(10, "John");
   cout << cPerson.WhoAmI() << endl;

   CWorker cWorker(35, "Mary", "On wacation");
   cout << cWorker.WhoAmI() << endl;

   CStudent cStudent(22, "Sandra", "Phisician");
   cout << cStudent.WhoAmI() << endl;

   return 0;
}```
示例分析
我们创建了一个新的数据类型`CPerson`来表示人。该类型用`iAge`和`sName`作为特征来描述一个人。如果还需要其他数据类型来表示工人或学生,就可以用OOP提供的一个很好的机制——继承来完成。工人首先是人,然后还有一些其他特征,我们用下面的代码把`CPerson`扩展为`CWorker`:

`class CWorker : public CPerson`
也就是说,`CWorker`从`CPerson`类继承而来。`CWorker`类不仅具有基类`CPerson`的所有特征和方法,还有一个对工人而言非常重要的特征`sEmploymentStatus`。接下来,我们还要创建一个学生数据类型。除了年龄和名字,学生也还具有其他特征。同理,我们用下面的代码把`CPerson`扩展为`CStudent`:

`class CStudent : public CPerson`
声明一个对象时,要调用它的构造函数。这里要注意的是:声明一个派生类的对象时,先调用基类的构造函数,后调用派生类的构造函数。如下代码所示:

CWorker( int iAge, char sName, char sEmploymentStatus )
 : CPerson( iAge, sName )
{
  strcpy_s( this->sEmploymentStatus, 32, sEmploymentStatus );
}`
注意看CWorker构造函数的原型,其形参列表后面有一个:(冒号),后面调用的是基类的构造函数,如下代码所示。在创建CPerson时,需要两个参数iAgesName

CPerson(iAge, sName)
调用析构函数的顺序要反过来,即先调用派生类的析构函数,后调用基类的析构函数。

一图胜千言,CPersonCWorkerCStudent类对象分别如图1.2所示。


714c8486e9f6fc1bebecca3beb5ea061dbdd720d

图1.2 CPerson、CWorker和CStudent类对象

可以针对用户自定义的类型来定义运算符的含义,如前面例子中的CComplex。这样做非常好,当cc1c2是复数时,c = c1 + c2比c = ComplexAdd(c1, c2)更直观更容易理解。

要让编译器能处理用户自定义的类型,就必须实现运算符函数或重载相应的函数。假设,有两个矩阵m1m2和一个矩阵表达式m = m1 + m2。编译器知道如何处理基本类型(如,把两个整数相加),但如果事先没有定义CMatrix operator+(const CMatrix& m1, const CMtrix& m2)函数,编译器就不知道如何计算矩阵加法。

覆盖(override)方法也是一种特性,允许派生类在基类已经实现某方法的前提下提供自己的特定实现。如前面例子中的WhoAmI方法所示,其输出如下:

I am a person 
I am a worker 
I am a student```
虽然每个类中的方法名相同,但它们却是不同的方法,有不同的功能。我们可以说,`CPerson`的派生类覆盖了`WhoAmI`方法。

更多讨论
相关文章
|
27天前
|
监控 Linux 测试技术
C++零拷贝网络编程实战:从理论到生产环境的性能优化之路
🌟 蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕C++与零拷贝网络编程,从sendfile到DPDK,实战优化服务器性能,毫秒级响应、CPU降60%。分享架构思维,共探代码星辰大海!
|
19天前
|
安全 Java 编译器
C++进阶(1)——继承
本文系统讲解C++继承机制,涵盖继承定义、访问限定符、派生类默认成员函数、菱形虚拟继承原理及组合与继承对比,深入剖析其在代码复用与面向对象设计中的应用。
|
3月前
|
C语言 C++
【实战指南】 C/C++ 枚举转字符串实现
本文介绍了在C/C++中实现枚举转字符串的实用技巧,通过宏定义与统一管理枚举名,提升代码调试效率并减少维护错误。
289 60
|
3月前
|
程序员 编译器 C++
【实战指南】C++ lambda表达式使用总结
Lambda表达式是C++11引入的特性,简洁灵活,可作为匿名函数使用,支持捕获变量,提升代码可读性与开发效率。本文详解其基本用法与捕获机制。
147 43
|
7月前
|
监控 Linux C++
【实战指南】4步实现C++插件化编程,轻松实现功能定制与扩展(2)
本文是《4步实现C++插件化编程》的延伸,重点介绍了新增的插件“热拔插”功能。通过`inotify`接口监控指定路径下的文件变动,结合`epoll`实现非阻塞监听,动态加载或卸载插件。核心设计包括`SprDirWatch`工具类封装`inotify`,以及`PluginManager`管理插件生命周期。验证部分展示了插件加载与卸载的日志及模块状态,确保功能稳定可靠。优化过程中解决了动态链接库句柄泄露问题,强调了采纳用户建议的重要性。
250 94
【实战指南】4步实现C++插件化编程,轻松实现功能定制与扩展(2)
|
7月前
|
人工智能 程序员 C++
【实战经验】C/C++右移高位补0还是1?
本文探讨了C/C++中右移运算时高位补0还是补1的问题。通过示例代码分析,揭示了右移规则:无符号类型高位补0;有符号类型根据正负决定(正数补0,负数补1)。文中列举了可能导致错误的场景,并提供了两种规避措施——使用无符号类型和掩码校正,确保结果符合预期。最后总结指出,右移运算虽常见,但若处理不当易引发隐晦Bug,需谨慎对待。
414 93
|
4月前
|
存储 安全 Java
c++--继承
c++作为面向对象的语言三大特点其中之一就是继承,那么继承到底有何奥妙呢?继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用,继承就是类方法的复用。
110 0
|
7月前
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
408 6
|
9月前
|
C++ 开发者
C++学习之继承
通过继承,C++可以实现代码重用、扩展类的功能并支持多态性。理解继承的类型、重写与重载、多重继承及其相关问题,对于掌握C++面向对象编程至关重要。希望本文能为您的C++学习和开发提供实用的指导。
144 16
|
11月前
|
自然语言处理 编译器 Linux
告别头文件,编译效率提升 42%!C++ Modules 实战解析 | 干货推荐
本文中,阿里云智能集团开发工程师李泽政以 Alinux 为操作环境,讲解模块相比传统头文件有哪些优势,并通过若干个例子,学习如何组织一个 C++ 模块工程并使用模块封装第三方库或是改造现有的项目。
811 56

热门文章

最新文章