C++ - 在容器(container)中 使用继承(inheritance)和虚函数(virtual function)

本文主要是介绍C++ - 在容器(container)中 使用继承(inheritance)和虚函数(virtual function),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

容器不支持混合类型, 如果直接把派生类对象, 存入基类容器中, 则无法使用派生-基转换(derived-base conversion);

因为转换只能发生在指针和引用 过程中, 不能发生在 对象直接赋值, 如果是直接转换, 则会产生截断(sliced down);

即派生类部分被切除, 只留下基类部分; 所以存入容器中的派生类 输出为基类部分 的虚函数;

如果想在容器中, 进行继承, 则需要使用指针, 包括智能指针(如:shared_ptr<>), 则会输出派生类的覆写(override)版本的虚函数;

 

代码:

[cpp]  view plain copy
  1. /* 
  2.  * CppPrimer.cpp 
  3.  * 
  4.  *  Created on: 2013.11.12 
  5.  *      Author: Caroline 
  6.  */  
  7.   
  8. /*eclipse cdt*/  
  9.   
  10. #include <iostream>  
  11. #include <string>  
  12. #include <vector>  
  13. #include <memory>  
  14. #include <cstddef>  
  15.   
  16. using namespace std;  
  17.   
  18. class Quote {  
  19. public:  
  20.     Quote() = default;  
  21.     Quote (const std::string& book, double sales_price) :  
  22.         bookNo (book), price (sales_price) {}  
  23.     std::string isbn() const { return bookNo; }  
  24.     virtual double net_price (std::size_t n) const { return n* price; } //虚函数  
  25.     virtual ~Quote() = default//动态绑定析构器  
  26. private:  
  27.     std::string bookNo;  
  28. protected//受保护类型  
  29.     double price = 0.0;  
  30. };  
  31.   
  32. class Disc_quote : public Quote { //抽象基类  
  33. public:  
  34.     Disc_quote() = default;  
  35.     Disc_quote (const std::string& book, double price, std::size_t qty, double disc) :  
  36.         Quote(book, price), quantity (qty), discount (disc) {}  
  37.     double net_price (std::size_tconst = 0; //纯虚函数  
  38. protected:  
  39.         std::size_t quantity = 0;  
  40.         double discount = 0.0;  
  41. };  
  42.   
  43. class Bulk_quote final : public Disc_quote { //final限定词, 无法被继承  
  44. public:  
  45.     Bulk_quote() = default;  
  46.     Bulk_quote(const std::string& book, double p, std::size_t qty, double disc) :  
  47.         Disc_quote(book, p, qty, disc) {} //使用基类的构造器  
  48.     double net_price(std::size_t cnt) const override;  
  49. };  
  50.   
  51. double Bulk_quote::net_price(std::size_t cnt) const  
  52. {  
  53.     if (cnt >= quantity)  
  54.         return cnt * (1-discount) * price;  
  55.     else  
  56.         return cnt * price;  
  57. }  
  58.   
  59. double print_total(std::ostream &os, const Quote& item, std::size_t n)  
  60. {  
  61.     double ret = item.net_price(n);  
  62.     os << "ISBN: " << item.isbn() << " # sold: " << n << " total due: " << ret << std::endl;  
  63.     return ret;  
  64. }  
  65.   
  66. int main (void) {  
  67.   
  68.     //正常存放, 无法调用派生类的虚函数  
  69.     std::vector<Quote> basket;  
  70.     basket.push_back(Quote("CppPrimer", 50));  
  71.     basket.push_back(Bulk_quote("CppPrimer", 50, 10, .25));  
  72.     std::cout << "Bulk_quote : " << basket.back().net_price(20) << std::endl;  
  73.   
  74.     //使用指针存放, 可以正确调用  
  75.     std::vector<std::shared_ptr<Quote> > sbasket;  
  76.     sbasket.push_back(std::make_shared<Quote>("CppPrimer", 50));  
  77.     sbasket.push_back(std::make_shared<Bulk_quote>("CppPrimer", 50, 10, .25));  
  78.     std::cout << "Bulk_quote : " << sbasket.back()->net_price(20) << std::endl;  
  79.   
  80.   
  81.     return 0;  
  82.   
  83. }  


输出:

[plain]  view plain copy
  1. Bulk_quote : 1000  
  2. Bulk_quote : 750  

这篇关于C++ - 在容器(container)中 使用继承(inheritance)和虚函数(virtual function)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1049375

相关文章

Python中conda虚拟环境创建及使用小结

《Python中conda虚拟环境创建及使用小结》本文主要介绍了Python中conda虚拟环境创建及使用小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录0.前言1.Miniconda安装2.conda本地基本操作3.创建conda虚拟环境4.激活c

Spring中@Lazy注解的使用技巧与实例解析

《Spring中@Lazy注解的使用技巧与实例解析》@Lazy注解在Spring框架中用于延迟Bean的初始化,优化应用启动性能,它不仅适用于@Bean和@Component,还可以用于注入点,通过将... 目录一、@Lazy注解的作用(一)延迟Bean的初始化(二)与@Autowired结合使用二、实例解

SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)

《SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)》本文介绍了如何在SpringBoot项目中使用Jasypt对application.yml文件中的敏感信息(如数... 目录SpringBoot使用Jasypt对YML文件配置内容进行加密(例:数据库密码加密)前言一、J

Spring Boot 中正确地在异步线程中使用 HttpServletRequest的方法

《SpringBoot中正确地在异步线程中使用HttpServletRequest的方法》文章讨论了在SpringBoot中如何在异步线程中正确使用HttpServletRequest的问题,... 目录前言一、问题的来源:为什么异步线程中无法访问 HttpServletRequest?1. 请求上下文与线

golang panic 函数用法示例详解

《golangpanic函数用法示例详解》在Go语言中,panic用于触发不可恢复的错误,终止函数执行并逐层向上触发defer,最终若未被recover捕获,程序会崩溃,recover用于在def... 目录1. panic 的作用2. 基本用法3. recover 的使用规则4. 错误处理建议5. 常见错

在 Spring Boot 中使用异步线程时的 HttpServletRequest 复用问题记录

《在SpringBoot中使用异步线程时的HttpServletRequest复用问题记录》文章讨论了在SpringBoot中使用异步线程时,由于HttpServletRequest复用导致... 目录一、问题描述:异步线程操作导致请求复用时 Cookie 解析失败1. 场景背景2. 问题根源二、问题详细分

从零教你安装pytorch并在pycharm中使用

《从零教你安装pytorch并在pycharm中使用》本文详细介绍了如何使用Anaconda包管理工具创建虚拟环境,并安装CUDA加速平台和PyTorch库,同时在PyCharm中配置和使用PyTor... 目录背景介绍安装Anaconda安装CUDA安装pytorch报错解决——fbgemm.dll连接p

Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)

《Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)》文章介绍了如何使用dhtmlx-gantt组件来实现公司的甘特图需求,并提供了一个简单的Vue组件示例,文章还分享了一... 目录一、首先 npm 安装插件二、创建一个vue组件三、业务页面内 引用自定义组件:四、dhtmlx

使用Python创建一个能够筛选文件的PDF合并工具

《使用Python创建一个能够筛选文件的PDF合并工具》这篇文章主要为大家详细介绍了如何使用Python创建一个能够筛选文件的PDF合并工具,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录背景主要功能全部代码代码解析1. 初始化 wx.Frame 窗口2. 创建工具栏3. 创建布局和界面控件4

一文详解如何在Python中使用Requests库

《一文详解如何在Python中使用Requests库》:本文主要介绍如何在Python中使用Requests库的相关资料,Requests库是Python中常用的第三方库,用于简化HTTP请求的发... 目录前言1. 安装Requests库2. 发起GET请求3. 发送带有查询参数的GET请求4. 发起PO