添加问题:

练手创建一个表示各种不同包裹的继承层次。

在写代码时:要求vector来实现多态性 , 用基类指针变量指向子类对象。

前面的父类和子类定义:

//创建一个表示各种不同包裹的继承层次
#include <iostream>
#include <algorithm>
#include <vector>
#include<iomanip>//输出对齐头文件
using namespace std;struct people     //定义结构体存寄/收件人信息
{string name;   //姓名 string state;       //省
};class Package   //基类
{
private: struct people sender;  //代表寄件人struct people rec;  //收件人信息 double unit_cost;     //每盎司费用 public:double weight;    //存储包裹重量(以盎司计)double calculateCost();Package(struct people,struct people,double,double);    //构造函数 string Getsender();   //获得发送者的地址信息 string Getrecname();      //获得接收者的地址信息 double GetWeight();   //获得包裹重量,以供派生类使用 double GetCostPerOunce();      //获得每盎司费用,以供派生类使用
};//构造函数
Package::Package(struct people sender_,struct people rec_,double unit_cost_,double weight_):sender(sender_),rec(rec_),unit_cost(unit_cost_),weight(weight_)//初始化这些值
{   weight=weight_>0?weight_:1;      //确保重量为正值 unit_cost=unit_cost_>0?unit_cost_:1;      //确保每盎司费用为正值
}double Package::calculateCost()
{double sum_cost;sum_cost=weight*unit_cost;return sum_cost;
}string Package::Getsender()    //获得发送者的地址信息,以供派生类使用
{return sender.state;
}string Package::Getrecname()    //获得接收者的地址信息,以供派生类使用
{return rec.state;
}double Package::GetWeight()     //获得包裹重量,以供派生类使用
{return weight;
}double Package::GetCostPerOunce()    //获得每盎司费用,以供派生类使用
{return unit_cost;
}//派生类
class TwoDayPackage:public Package    //两日包裹类
{
public:TwoDayPackage(struct people,struct people,double,double,double);   //构造函数 double calculateCost();
private:double normal_send_fee;     //平寄费
};
//构造函数
TwoDayPackage::TwoDayPackage(struct people sender_,struct people rec_,double unit_cost_,double normal_send_fee_,double weight_):Package(sender_,rec_,unit_cost_,weight_),normal_send_fee(normal_send_fee_)
{
}double TwoDayPackage::calculateCost()    //TwoDayPackage类重新定义基类的成员函数 calculateCost来计算运输费用
{return normal_send_fee+Package::calculateCost();       //平寄费加由基类Package的calculateCost函数计算得到的基于重量的费用
} //连夜包裹类
class OvernightPackage:public Package
{
public:OvernightPackage(struct people,struct people,double,double,double);  //构造函数 double calculateCost();
private:double normal_per_ounce_fee;  //付给连夜快递服务的每盎司额外费用
};//构造函数
OvernightPackage::OvernightPackage(struct people sender_,struct people rec_,double unit_cost_,double normal_per_ounce_fee_,double weight_):Package(sender_,rec_,unit_cost_,weight_),normal_per_ounce_fee(normal_per_ounce_fee_)
{
} double OvernightPackage::calculateCost()       //OvernightPackage类重新定义基类的成员函数 calculateCost来计算费用
{return GetWeight()*(normal_per_ounce_fee+GetCostPerOunce());      //平寄费加由基类Package的calculateCost函数计算得到的基于重量的费用
}

main()中:

 //vector来实现多态性  vector<Package *>vec(2);//包含package指针的vector对象,指针指向 twodaypackage对象和 overnightpackage对象 //基类指针变量指向子类对象    vec[0]=new TwoDayPackage(sender,rec,0.5,5,sender_weight);// 包裹2.5盎司,每盎司0.5元,平寄费5元, 返回值5+2.5x0.5=6.25元vec[1]=new OvernightPackage(sender,rec,0.5,0.2,sender_weight);//包裹2.5盎司,每盎司0.5元,连夜快递每盎司额外费用0.2元,返回值 2.5x(0.5+0.2)=1.75元cout<<endl;

调用方式:

//调用每个Package的calculateCost成员函数并输出结果 //跟踪记录该vector中所有Package的总的运输费用,并在循环遍历结束时显示此总费用 double sumcost=0;//总的运输费用 for(int i=0;i<vec.size();i++){double cost=vec[i]->calculateCost(); if(i==0)cout <<"twodaypackage类所需费用为:"<<cost<< endl;elsecout <<"overnightpackage类所需费用为:"<<cost<< endl; sumcost+= cost;} cout<<"该vector中所有Package的总的运输费用为:"<<sumcost<<endl; 

然而出现了调用的结果仍是基类中calculateCost()函数的情况。最后了解了有关虚函数的定义。

进行了修改。

解决方式:

修改了Package的基类

class Package   //基类
{
private: struct people sender;  //代表寄件人struct people rec;  //收件人信息 double unit_cost;     //每盎司费用 public:double weight;    //存储包裹重量(以盎司计)virtual double calculateCost();Package(struct people,struct people,double,double);    //构造函数 string Getsender();   //获得发送者的地址信息 string Getrecname();      //获得接收者的地址信息 double GetWeight();   //获得包裹重量,以供派生类使用 double GetCostPerOunce();      //获得每盎司费用,以供派生类使用
};

添加了virtual关键词。

virtual double calculateCost();

此时为同名同参函数,基类虚函数、派生类实函数,故后续调用都是调用派生类函数。

暂时还是不太熟练 同名同参条件下,基类和派生类都能调用的通用情况,后续在学习吧。

借鉴理论参考:(非常感谢CSDN博主「why you so」的原创文章)

原文链接:https://blog.csdn.net/qq_38650447/article/details/123368853

1、基类指针指向派生类对象
    同名同参函数,基类虚函数、派生类实函数
        只要调用该名字的函数,都是调用派生类函数
    同名同参函数,基类实函数,派生类虚函数
        只要调用该名字的函数,都是调用基类函数
            
    同名同参函数,基类虚函数,派生类虚函数
        只要调用该名字的函数,都是调用派生类对象
    同名同参函数,基类实函数,派生类实函数
        只要调用该名字的函数,都是调用基类函数
    
    得出结论:基类指针pBase指向派生类对象basePlus时,
    基类与派生类都含有同名同参函数,如果是一虚一实,
    pBase调用他们中的实函数;如果同实,调用基类函数;
    同虚,调用派生类函数
    注:如果是一定要调用基类的函数,可以使用pBase::func
        如果是一定要调用派生类函数,可以使用basePlus::func,只能在派生类中调用,基类不能调用
        
    一般是同实同虚。

C++的基类指针指向派生类对象,vector实现多态性相关推荐

  1. C++基类指针指向派生类(指针)

    我们常用基类指针指向派生类对象来实现多态性. 私有继承不允许基类指针指向派生类 基类指针只能访问到基类中含有的公有成员. 当用基类指针指向派生类对象在动态分配堆上内存的时候,析构函数必须是虚函数! 成 ...

  2. C++通过基类指针delete派生类数组,析构函数是虚函数,程序为什么会崩溃? https://www.zhihu.com/question/30838092/answer/49623765

    https://www.zhihu.com/question/30838092/answer/49623765 C++通过基类指针delete派生类数组,析构函数是虚函数,程序为什么会崩溃? 代码如下 ...

  3. 【C++】【读个小故事就弄懂】为什么基类指针可以指向派生类对象,而派生类指针却不可以指向基类对象?(最易懂最有趣最生动的举例)

        在内存中,一个基类类型的指针是覆盖N个单位长度的内存空间.     当其指向派生类的时候,由于派生类元素在内存中堆放是:前N个是基类的元素,N之后的是派生类的元素.     于是基类的指针就可 ...

  4. 指向派生类对象的基类指针与虚函数

    看如下代码: CSales   aSales("崔贤"); CSales* pSales; CWage* pWager; pSales=&aSales; pWager=&a ...

  5. C++>继承,继承方式及其比较,子类和父类对象指针,派生类的默认成员函数,虚继承,继承与友元,继承与静态成员

    继承 继承的概念与定义 概念: 继承是指一个子类(或称为派生类)继承父类(或称为基类)的特征(属性和操作).继承是面向对象程序设计时实现代码复用的重要手段,它允许在原有的类的基础上进行扩展,增加功能, ...

  6. 非多态的继承情况下,基类指针可以指向派生类对象么?

    class Base { // 基类 public:Base(int aa=88) : a(aa) {}void f() { // 非virtualcout<<"Base&quo ...

  7. 基类数组存放派生类_永远不要将派生类数组赋值给基类类型指针

    C.152: Never assign a pointer to an array of derived class objects to a pointer to its base C.152:永远 ...

  8. 虚函数之定义一个基类Shape,在此基础上派生出Rectangle和Circle再使用Rectangle类创建一个派生类Square。

    定义一个基类Shape,在此基础上派生出Rectangle和Circle,二者都有getArea( )函数计算对象的面积,再使用Rectangle类创建一个派生类Square.将getArea()改造 ...

  9. 不同派生方式下基类成员在派生类中的可访问范围属性

    不同派生方式下基类成员在派生类中的可访问范围属性 派生方式 派生方式 派生方式 基类成员 公有派生 私有派生 保护派生 私有成员 不可访问 不可访问 不可访问 保护成员 保护 私有 保护 公有成员 公 ...

最新文章

  1. BZOJ 3997 [TJOI2015]组合数学(单调DP)
  2. 【Spring学习】RestTemplate访问Rest服务总结
  3. android mysql开发工具_Android开发工具--adb的使用
  4. zzulioj 1065:统计数字字符个数
  5. Hibernate一对一主键单向关联
  6. unity怪物攻击玩家减血_怪物猎人发布15周年 — 回顾历代封面怪之三大传奇怪物...
  7. python BeautifulSoup对应关系
  8. 图像压缩编码码matlab实现——DM编码
  9. c语言对fpga编程,利用C语言对FPGA计算解决方案进行编程方法介绍
  10. 打太极不协调的二三事
  11. 记录一次海康威视录像机重置密码的经历
  12. 转:Django新手需要注意的10个要点
  13. linux 设置用户只读,Linux只读账号配置
  14. 栈的应用-数制转换(C语言数据结构)
  15. 张小龙-年薪近3亿的微信之父,他是如何做到的?
  16. 使用微信web开发者工具调试微信企业号页面
  17. 操作系统实验Ucore lab8+反馈队列
  18. PHPSTORM+phpstudy 显示waiting for incoming connection with ide key
  19. Office365 Exchange Online系列之邮箱大管家视频课程-李远-专题视频课程
  20. ionic3开发系列——实现对手机软件键盘按键的监听

热门文章

  1. 动物之美计算机教案,一年级美术下册第14课 可爱的动物教案
  2. Latex常用宏包\usepackage
  3. react中使用富文本编辑器,发布文章
  4. Kubernetes 北极星指标
  5. 第3节-Redis数据类型介绍以及应用
  6. FlowDroid + Soot-infoflow-android获取Android apk信息 2.9.0版2021最新版
  7. 全自动批量剪辑视频软件,手机上批量剪辑视频,视频批量剪辑软件如何剪辑
  8. HMC5883L磁力计常见问题解答
  9. 基于JAVA基于网络平台个人博客系统计算机毕业设计源码+系统+lw文档+部署
  10. JVM 学习笔记(三)类加载与字节码技术内存模型