西南科技大学C++程序设计实验八(多态一)

一、实验目的

1. 掌握多态性的分类;

2. 动态多态性-虚函数;

3. 理解纯虚函数的概念。

二、实验任务

1.分析以下程序,改正程序错误,写出程序输出结果,并按要求:

(1)思考:输出结果中为什么类A是8个字节,类B是12个字节?分析虚函数的类的结构特点

A的字节大小为: 4int+4 (v_ptr)=8  B的字节大小为: 4int+4int+4 (v_ptr)=12

(2)回答程序中标注的思考题1-5,总结虚函数的调用为什么要用基类对象指针?基类对象指针与派生类对象指针的使用区别是什么?

为什么要用基类对象指针:

当一个派生类对象赋值给基类指针或引用的时候,该指针或引用将指向派生类对象中的虚函数表指针。

在程序执行时,通过基类指针或引用调用虚函数,会调用派生类中的该函数,这种行为被称为动态绑定或动态多态性。

基类对象指针与派生类对象指针的使用区别:

可以将一个父类指针指向一个子类对象,但不能子类指针能否指向父类对象,因为子类中有些信息父类没有,如果用子类指针访问的时候很可能访问到父类没有的一些属性及函数,会出错!

#include <iostream>
using namespace std;
class A
{
public:
    int a;
    A()   {a=2;}
    int geta()          {return a; }
    virtual void show()           {cout<<"a="<<a<<endl; }
};
class B:public A
{
public:
    int b;
    B(){b=6;}
    int getb(){        return b;   }
     void show()
     {
        A::show();
        cout<<"b="<<b<<endl;
    }
};
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    A first,*p1;
    B second,*p2;
    cout<<"sizeof(A)="<<sizeof(A)<<"  sizeof(p1)="<<sizeof(p1)<<endl; //思考:输出结果?
    cout<<"sizeof(B)="<<sizeof(B)<<" sizeof(p2)="<<sizeof(p2)<<endl;
    p1=&second//基类对象指针指向派生类对象
    p1->show();  //思考1:此时指针调用的是派生类中的show()函数还是基类中的?
    cout<<p1->geta()<<endl//思考2:程序是否能够正确输出?得出什么结论?
    cout<<p1->getb()<<endl;  //思考3:程序是否能够正确输出,若不能正确输出,为什么?
    p2=&second; //派生类对象指针指向派生类对象
    cout<<p2->geta()<<endl//思考4:程序是否能够正确输出?得出什么结论?
    cout<<p2->getb()<<endl//思考5:程序是否能够正确输出,若不能正确输出,为什么?
    return a.exec();
}

实验思考题回答与结果分析:

(1)在X86的条件下,sizeof:A为8  sizeof:B 为4;

(2)此时调用的是派生类的show()函数

(3)程序可以正常输出,p1为基类指针,可以访问基类的非虚构函数

(4)不能,p1为基类指针不能访问派生类中的非虚函数

(5)程序能够正确输出,p2为派生类指针。继承了基类中的geta()非成员函数,可以直接调用

(6)程序能够正确输出,p2可以直接getb()非成员函数

2、分析以下程序,写出程序运行结果,说明为什么要把析构函数声明为虚函数,要求:

  1. 分别将析构函数定义为虚函数,非虚函数两种情况调试程序。

当将析构函数定义为虚函数,基类与派生类函数全都得到了析构

将析构函数定义为非虚函数,派生类没有析构

 

  1. 思考如果把A类中的析构函数前的virtual去掉(即不声明为虚析构函数),通多基类对象指针是否会正确释放派生类对象所占内存?

不能

 
#include <iostream>
using namespace std;
class A
{
public:
    A(){}
    virtual~A()
    {
        cout<<"Delete class A\n";
    }
};
class B : public A{
public:
    B(){}
    ~B()
    {
        cout<<"Delete class B\n";
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/206102.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

导入JDBC元数据到Apache Atlas

前言 前期实现了导入MySQL元数据到Apache Atlas, 由于是初步版本&#xff0c;且功能参照Atlas Hive Hook&#xff0c;实现的不够完美 本期对功能进行改进&#xff0c;实现了导入多种关系型数据库元数据到Apache Atlas 数据库schema与catalog 按照SQL标准的解释&#xff0c;…

从 Kindle 文件中提取内容:GroupDocs.Parser V23.11

从 Kindle 文件中提取内容 2023 年 12 月 6 日 GroupDocs.Parser V23.11 增加了对 Kindle 文档格式的支持&#xff0c;支持从 Kindle 电子书和文档中提取文本和元数据。 GroupDocs.Parser 是一款全面的文档解析解决方案&#xff0c;使您能够从多种文档格式中提取文本、元数据和…

SLAM算法与工程实践——SLAM基本库的安装与使用(3):Pangolin库

SLAM算法与工程实践系列文章 下面是SLAM算法与工程实践系列文章的总链接&#xff0c;本人发表这个系列的文章链接均收录于此 SLAM算法与工程实践系列文章链接 下面是专栏地址&#xff1a; SLAM算法与工程实践系列专栏 文章目录 SLAM算法与工程实践系列文章SLAM算法与工程实践…

Linux--文件权限与shell外壳的理解

目录 一.Linux的用户与用户切换&#xff0c;提权 二.对文件权限的理解 1.文件权限角色的权限文件属性 2.Linux中的三种角色 3.为什么会存在所属组这个角色 4.文件属性的意义 4.1.第一个字母的意义 4.2 第2——第10个字母的意义 4.3修改文件权限的方法 三.目录权限 四…

【1day】DocCms 某接口SQL注入漏洞学习

注:该文章来自作者日常学习笔记,请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与作者无关。 目录 一、漏洞描述 二、影响版本 三、资产测绘 四、漏洞复现 五、漏洞修

git分支修改名称并推送到远程

1. git branch -m oldBranchName newBranchName 修改本地分支名称,这将在本地仓库中重命名分支&#xff0c;但不会影响远程仓库。 2. git push origin :oldBranchName 命令用于删除远程仓库中的旧分支&#xff0c;通过将分支名前面的冒号 : 添加到命令中&#xff0c;可以将…

文本润色工具有哪些,高质量的文本润色软件

在当今信息过载的时代&#xff0c;文本的重要性愈发凸显。即便是最精心构思的文章&#xff0c;若未经过仔细的润色&#xff0c;也难以达到最佳的表达效果。本文将专心分享文本润色工具的种类。 文本润色工具的种类 文本润色工具根据其功能和应用范围可以分为多个种类&#xff…

GO设计模式——5、建造者模式(创建型)

目录 建造者模式&#xff08;Builder Pattern&#xff09; 建造者模式的核心角色 优缺点 使用场景 注意事项 代码实现 建造者模式&#xff08;Builder Pattern&#xff09; 建造者模式&#xff08;Builder Pattern&#xff09;是将一个复杂对象的构建与它的表示分离&…

js/jQuery常见操作 之 jQuery操作复选框的常见问题

js/jQuery常见操作 之 jQuery操作复选框的常见问题 1. js/jQuery的其他一些常见基础操作2. 全选/全不选问题2.1 效果2.2 实现代码2.2.1 简单js实现2.2.2 jQuery实现2.2.2.1 注意语法&#xff08;区别jQuery版本&#xff09;2.2.2.2 完整代码实现 3. jQuery实现点击 行tr 实现ch…

石头剪刀布python

石头剪刀布 import random AI_result [石头,剪刀,布] result random.choice(AI_result) User input("请输入石头/剪刀/布&#xff1a;") Win_list [[石头,剪刀],[剪刀,布],[布,石头]] print("AI出的",result,"玩家出的",User) if result …

【Java 基础】21 多线程同步与锁

文章目录 1.存在的问题2.使用同步解决问题1) synchronized2) volatile3) 锁 总结 用多线程过程中&#xff0c;有可能出现 多个线程同时处理&#xff08;获取或修改等&#xff09;同一个数据&#xff0c;这个时候就 会发生数据不同步的问题&#xff0c; 因此出现了同步和锁来…

APP备案(Android) - 获取签名证书公钥、MD5

因为近期刚针对各应用平台对APP备案时间节点要求进行了统一整理&#xff0c;然后隔天就被要求提供一下app相关的的公钥和MD5&#xff0c;虽然很快就解决了这个事情&#xff0c;但忍不住又稍微衍生了一下&#xff0c;但行小步&#xff0c;莫问远方吧 关联Blog APP备案(Android)…

ARM虚拟化与车联网安全应用

ARM虚拟化简介 ARM虚拟化是指在ARM架构下实现虚拟化技术的方法和技术。虚拟化技术允许在一台物理机上运行多个虚拟机实例&#xff0c;每个虚拟机实例都能够独立运行操作系统和应用程序。 ARM虚拟化的主要目标是提供高效、可扩展和安全的虚拟化环境。以下是一些关键概念和技术…

【docker】怎么查看docker镜像的dockerfile、docker history 显示不全

参考&#xff1a; https://blog.csdn.net/weixin_40161254/article/details/116458523 https://blog.csdn.net/m0_45406092/article/details/119037604 对于本地的镜像&#xff0c;我们使用docker history weblogic:latest 命令来查看它的构建命令&#xff0c;如图可以看到运…

芯知识 | 什么是单片机语音芯片?

在电子技术的飞速发展下&#xff0c;语音芯片成为了日常生活中不可或缺的一部分。而在语音芯片领域&#xff0c;单片机语音芯片占据了重要的地位。那么&#xff0c;究竟什么是单片机语音芯片呢&#xff1f; 一、定义与概念 首先&#xff0c;我们来了解一下单片机和语音芯片的…

java多线程(二)线程池

目录 java线程池 线程池应用场景&#xff1a; 如何创建线程池&#xff1a; 有什么区别&#xff1a; 不同线程池对应的应用场景 案例 输出结果 java线程池 Java线程池是一种预先创建一定数量的线程&#xff0c;并将任务提交给这些线程执行的机制。线程池可以避免频繁创建…

ExecutorService、Callable、Future实现有返回结果的多线程原理解析

原创/朱季谦 在并发多线程场景下&#xff0c;存在需要获取各线程的异步执行结果&#xff0c;这时&#xff0c;就可以通过ExecutorService线程池结合Callable、Future来实现。 我们先来写一个简单的例子—— public class ExecutorTest {public static void main(String[] ar…

Vulnhub项目:EMPIRE: BREAKOUT

一、靶机地址 靶机地址&#xff1a;Empire: Breakout ~ VulnHub 靶机介绍&#xff1a; 该靶机被定义为简单&#xff0c;但是如果没有找到&#xff0c;那就难度成中等了&#xff01; 二、渗透过程 老三样&#xff0c;发现目标&#xff0c;这里用 arp-scan 确定靶机 ip&#…

Java基础50题:14. 使用方法求最大值(2种方法)

概述 使用方法求最大值。 创建方法求两个数的最大值max2&#xff0c;随后再写一个求3个数的最大值函数max3。 要求&#xff1a; 在max3这个方法中&#xff0c;调用max2函数&#xff0c;来实现3个数的最大值计算。 方法一 【代码】 public class P14 {public static int max…

Java File类详解(下)练习二

第四题 需求&#xff1a;删除一个多级文件夹 import java.io.File;/*** 删除一个多级目录*/ public class FileDeletion {public static void main(String[] args) {File f new File("H:\\test\\aaa");deleteDir(f);}public static void deleteDir(File dir){// 进…