前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++基础(五).多态

C++基础(五).多态

作者头像
franket
发布2021-09-15 19:53:07
6280
发布2021-09-15 19:53:07
举报
文章被收录于专栏:技术杂记技术杂记

前言

C++语言是C语言的拓展,C语言是面向过程的,C++在C的基础上增加了面向对象的方法

什么是面向对象呢,面向对象就是将数据和对数据的加工方法打包在一起,进行模块化的调用,通过方法来进行数据交换的一种设计方法

Tip: 本人关于程序的认知,可以参看前面写的 一个运维人员的编程思维

面向对象的程序设计有四个主要特点:

  • 抽象
  • 封装
  • 继承
  • 多态

下面就通过C++来对面向对象的核心特性进行分享


概要


多态

多态性是指允许不同类的对象对同一消息作出响应

比如同样的加法,把两个时间加在一起和把两个整数加在一起肯定完全不同;又比如,同样的选择编辑-粘贴操作,在字处理程序和绘图程序中有不同的效果

多态性包括参数化多态性和包含多态性

多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题


相关概念

重载

同一可访问区内被声明的几个具有不同参数列(参数的类型,个数,顺序不同)的同名函数,根据参数列表确定调用哪个函数,重载不关心函数返回类型

隐藏

派生类的函数屏蔽了与其同名的基类函数,注意只要同名函数,不管参数列表是否相同,基类函数都会被隐藏

重写

重写也叫覆盖,是指派生类中存在重新定义的函数。其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。只有函数体不同(花括号内),派生类调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有virtual修饰

重载和重写的区别

  • 范围区别:重写和被重写的函数在不同的类中,重载和被重载的函数在同一类中
  • 参数区别:重写与被重写的函数参数列表一定相同,重载和被重载的函数参数列表一定不同
  • virtual的区别:重写的基类必须要有virtual修饰,重载函数和被重载函数可以被virtual修饰,也可以没有

隐藏和重写,重载的区别

  • 与重载范围不同:隐藏函数和被隐藏函数在不同类中
  • 参数的区别:隐藏函数和被隐藏函数参数列表可以相同,也可以不同,但函数名一定同;当参数不同时,无论基类中的函数是否被virtual修饰,基类函数都是被隐藏,而不是被重写

Tip: 引自 C++中重载、重写(覆盖)和隐藏的区别


友元

我们已知道类具备封装和信息隐藏的特性。只有类的成员函数才能访问类的私有成员,程式中的其他函数是无法访问私有成员的。非成员函数能够访问类中的公有成员,但是假如将数据成员都定义为公有的,这又破坏了隐藏的特性。另外,应该看到在某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响程式的运行效率

为了解决上述问题,提出一种使用友元的方案。友元是一种定义在类外部的普通函数,但他需要在类体内进行说明,为了和该类的成员函数加以区别,在说明时前面加以关键字friend。友元不是成员函数,但是他能够访问类中的私有成员。友元的作用在于提高程式的运行效率,但是,他破坏了类的封装性和隐藏性,使得非成员函数能够访问类的私有成员

友元能够是个函数,该函数被称为友元函数;友元也能够是个类,该类被称为友元类

友元函数

友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,他和普通函数相同,即在定义上和调用上和普通函数相同

友元类

友元除了前面讲过的函数以外,友元还能够是类,即一个类能够作另一个类的友元。当一个类作为另一个类的友元时,这就意味着这个类的任何成员函数都是另一个类的友元函数

Tip: 引自 C++中友元详解


代码示例

要求

用友元函数实现clock类的前置、后置单目运算符重载

代码语言:javascript
复制
  Clock c;
   (c++).showTime();
   (++c).showTime();

代码示例

clock.cpp

代码语言:javascript
复制
#include <iostream> //cout,endl 相关函数的声明在此
#include <stdlib.h> //exit 相关函数的声明在此
#include <stdio.h> //printf 相关函数的声明在此

using namespace std; //使用std命名空间

class Clock //定义一个时钟类
{
public:
  friend Clock operator ++ (Clock &c); //使用友元函数的方式对前置++运算符进行重载
  friend Clock operator ++ (Clock &c,int); //使用友元函数的方式对后置++运算符进行重载,注意这里使用别名的方式来引用被操作的对象,为了区别于前置重载,这里留出一个int类型的参数空位,但并不需要真实传参,(此项仅为C++语言中为示区别的约定,即便是其它类型的单目运算符也用int来占位)
  void showTime(); //声明一个显示方法
  Clock(int h=0,int m=0,int s=0); //Clock的构造函数,给出了默认值
private:
  int hour,minute,second; //成员变量
};

Clock::Clock(int h,int m,int s) //构造函数的实现 
{
  if( h<0 || h >23 ) //对hour参数进行检查
  {
    cout<<"error init Hour:"<<h<<endl;
    exit(1);
  }
  if( m<0 || m>59 ) //对minute参数进行检查
  {
    cout<<"error init Minute:"<<m<<endl;
    exit(1);
  }
  if( s<0 || s>59 ) //对second参数进行检查
  {
    cout<<"error init Second:"<<s<<endl;
    exit(1);
  }

  hour=h;
  minute=m;
  second=s; //进行相应的初始化
}


void Clock::showTime() //showTime的实现 
{
  printf("%02d:%02d:%02d\n",hour,minute,second);
}

Clock operator ++ (Clock &c) //前置++运算的实现 
{
  c.second++;
  if(c.second>=60) //对second溢出进位的判断和处理
  {
    c.second-=60;
    c.minute++;
    if(c.minute>=60) //对minute溢出进位的判断和处理
    {
      c.minute-=60;
      c.hour++;
      c.hour%=24; //对hour溢出进位的判断和处理
    }
  }
  return c; 
}

Clock operator ++ (Clock &c,int) //后置++运算的实现
{
  Clock old=c;
  ++c; //先调用前置++
  return old; //返回++操作之前的状态
}


int main()
{
  Clock c(23,59,59); 

  c.showTime();
  (++c).showTime(); //进行前置++测试
  c++.showTime(); //进行后置++测试
  c.showTime();

  return 0;
}

编译执行

代码语言:javascript
复制
emacs@ubuntu:~/c++$ alias gtx
alias gtx='g++ -Wall -g -o'
emacs@ubuntu:~/c++$ gtx clock.x clock.cpp
emacs@ubuntu:~/c++$ ./clock.x 
23:59:59
00:00:00
00:00:00
00:00:01
emacs@ubuntu:~/c++$

编译执行过程中没有报错,从结果来看,符合预期


总结

弄清下面概念对掌握c++很有帮助

  • 友元(函数/类)
  • 单目运算符(前置/后置)
  • 重载
  • 重写
  • 隐藏

原文地址http://soft.dog/2017/02/15/cpp-polymorphism-05/

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 概要
    • 多态
      • 相关概念
        • 重载
        • 隐藏
        • 重写
        • 重载和重写的区别
        • 隐藏和重写,重载的区别
      • 友元
        • 友元函数
        • 友元类
      • 代码示例
        • 要求
        • 代码示例
        • 编译执行
    • 总结
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档