c++虚函数纯虚函数详解加代码解释

news2024/11/28 8:30:24

c++虚函数纯虚函数详解加代码解释

  • 一.概念:
  • 二.虚函数示例及解析:
  • 三.纯虚函数示例及解析:
  • 四.验证和实际使用及解析:
    • 1.子类没有对父类的函数重载,mian()函数调用,是直接返回父类的值
    • 2.子类对父类的函数重载,mian()函数调用,是直接返回子类重载后的返回值
    • 3.子类对父类的函数重载,但子类调用自己函数,mian()函数调用时,报错,是因为,类的定义指向父类重新定义子类,父类中没有的子类也不能调用。
  • 五.总结:
  • 补充override关键字作用:

一.概念:

虚函数和纯虚函数是面向对象编程中的概念,用于实现多态性和抽象类特性。
虚函数(Virtual Function)是在基中声明的函数,通过在函数前面加上virtual关键字来标识。虚函数可以在派生类中被重写,实现函数的多态性。在运行时,根据对象的实际类型来确定调用哪个版本的虚函数。通过基类的指针或引用调用虚函数时,会根据指针或引用所指向的对象类型来调用相应的函数。
纯虚函数(Pure Virtual Function)是在基类中声明的没有实际实现的函数,通过在函数声明后面加上= 0来标识。纯虚函数用于定义接口,要求派生类必须实现函数。有了纯虚函数,基类就成为了抽象类,无法创建对象,只能作为其他类的基类来派生出新的类。
纯虚函数的作用是实现接口的统一和规范,确保派生类都实现了基类中定义的接口。纯虚函数可以在派类中重写,也可以不重写如果某个派类重写纯虚函数,那么该派生类也成为抽象类,无法创建对象。

二.虚函数示例及解析:

#include <iostream>
using namespace std;

class Animal {
public:
    virtual void speak() {
       cout << "Animal speaks!" <<endl;
    }
};

class Dog : public Animal {
public:
    void override() {
        cout << "Dog barks!" << endl;
    }
};

class Cat : public Animal {
public:
    void speak() {
        cout<< "Cat meows!" << endl;
    }
};

int main() {
    Animal* animal1 = new Dog();
    Animal* animal2 = new Cat();

    animal1->speak(); // 输出:Dog barks!
    animal2->speak(); // 输出:Cat meows!

    delete animal1;
    delete animal2;

    return 0;
}

在这里插入图片描述

虚函数是在基类中声明的具有虚函数特性的函数,通过在声明前加上键字virtual来标识。它允许在派生类中重写该函数,实现多态性。在运行时,根据对象的实际类型来确定调用哪个版本虚函数。
在上述中,Animal类是基类,其中的speak()函数被声明为虚Dog和Cat类是派生类,它们分别重写了speak()`函数。
在main()函数中,我们通过基类指针分别创建了Dog和Cat对象,并调用了speak()函数。由于speak()函数是虚函数,所以在运行时会根据对象的实际类型来确定调用哪个版本的函数因此,输出结果分别是"Dog barks!“和"Cat meows!”。

三.纯虚函数示例及解析:

#include <iostream>
using namespace std;


class Shape {
public:
    virtual double getArea() = 0;
};


class Rectangle : public Shape {
private:
    double length;
    double width;
public:
    Rectangle(double len, double wid) : length(len), width(wid) {}
    double getArea() override {
        cout << "Rectangle" << endl;
        return length*width;
    }
};


class Square : public Shape {
private:
    double length;
public:
    Square(double len) : length(len){}
    double getArea() override {
        cout << "Square" << endl;
        return length * length;
    }
};

class Circle : public Shape {
private:
    double radius;
 public:
        Circle(double r) : radius(r){}
        double getArea() override {
            cout << "Circle" << endl;
        return 3.14 * radius * radius;
    }
};

int main() {
    Shape* shape1 = new Rectangle(5, 4);
    Shape* shape2 = new Circle(3);
    Shape* shape3 = new Square(5);

    cout << "Area of rectangle: " << shape1->getArea() << endl;
    cout << "Area of circle: " << shape2->getArea() << endl;
    cout << "Area of square:" << shape3->getArea() << endl;

    delete shape1;
    delete shape2;
    delete shape3;

    return 0;
}

在这里插入图片描述

纯虚函数是在基类中声明的没有实际实现的函数,通过函数声明后加上= 0来标识。它用于定义接口求派生类必须实现该函数。
在上述代码中,Shape类是基类,其中的getArea()函数被声明为纯虚函数。Rectangle``Circle类是派生类,它们必须实现getArea()函数。
在main()函数中,我们通过基类指针分别创建了Rectangle和Circle,并调用了getArea()函数。由于getArea()函数是纯虚函数,所以基类Shape无法创建对象,只能通过派生类来实现具体的功能因此,输出结果分别是矩形的面积和圆的面。

四.验证和实际使用及解析:

1.子类没有对父类的函数重载,mian()函数调用,是直接返回父类的值

#include <iostream>
using namespace std;


class Shape {
public:
    virtual double getArea() = 0;
    virtual double getperimeter() {
        cout << "demo test" << endl;
        return 5;
    };
};


class Rectangle : public Shape {
private:
    double length;
    double width;
public:
    Rectangle(double len, double wid) : length(len), width(wid) {}
    double getArea() override {
        cout << "Rectangle" << endl;
        return length * width;
    }
};


int main() {
    Shape* shape1 = new Rectangle(5, 4);
    cout << "Area of rectangle: " << shape1->getArea() << endl;
    cout << "getperimeter of rectangle: " << shape1->getperimeter() << endl;


    delete shape1;

    return 0;
}

在这里插入图片描述

2.子类对父类的函数重载,mian()函数调用,是直接返回子类重载后的返回值

#include <iostream>
using namespace std;


class Shape {
public:
    virtual double getArea() = 0;
    virtual double getperimeter() {
        cout << "demo test" << endl;
        return 5;
    };
};


class Rectangle : public Shape {
private:
    double length;
    double width;
public:
    Rectangle(double len, double wid) : length(len), width(wid) {}
    double getArea() override {
        cout << "Rectangle" << endl;
        return length * width;
    }
    double getperimeter(){
        cout <<"getperimeter:getperimeter" << endl;
        return length * 2 + width * 2;
    }
};


int main() {
    Shape* shape1 = new Rectangle(5, 4);
    cout << "Area of rectangle: " << shape1->getArea() << endl;
    cout << "getperimeter of rectangle: " << shape1->getperimeter() << endl;


    delete shape1;

    return 0;
}

在这里插入图片描述

3.子类对父类的函数重载,但子类调用自己函数,mian()函数调用时,报错,是因为,类的定义指向父类重新定义子类,父类中没有的子类也不能调用。

将:Shape* shape1 = new Rectangle(5, 4);
修改为:Rectangle* shape1 = new Rectangle(5, 4);

我们才能调用子类中父类没有定义的函数

#include <iostream>
using namespace std;


class Shape {
public:
    virtual double getArea() = 0;
};


class Rectangle : public Shape {
private:
    double length;
    double width;
public:
    Rectangle(double len, double wid) : length(len), width(wid) {}
    double getArea() override {
        cout << "Rectangle" << endl;
        return length * width;
    }
    double getperimeter(){
        cout <<"getperimeter:getperimeter" << endl;
        return length * 2 + width * 2;
    }
};


int main() {
    Rectangle* shape1 = new Rectangle(5, 4);
    cout << "Area of rectangle: " << shape1->getArea() << endl;
    cout << "getperimeter of rectangle: " << shape1->getperimeter() << endl;


    delete shape1;

    return 0;
}

在这里插入图片描述

五.总结:

虚函数用于实现多性,允许在派生类中重写基类的函数。
纯虚函数用于定义接口,要求派生必须实现函数,可以在派生类中重写或不重写。

补充override关键字作用:

如果派生类在虚函数声明时使用了override描述符,那么该函数必须重载其基类中的同名函数,否则代码将无法通过编译

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

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

相关文章

一键清除磁盘垃圾工具分享,绿色快速好用

下载&#xff1a;https://download.csdn.net/download/weixin_43097956/88541564

2023年中国机动车拍卖网络化趋势加速,网络拍卖专场数量大幅上升至47489场[图]

2022年&#xff0c;由于机动车拍卖网络化趋势继续加速&#xff0c;网络拍卖专场数量大幅上升&#xff0c;全国机动车专场拍卖会高达59450场&#xff0c;较上年攀升125.31%。在389家拍卖企业中&#xff0c;举办场次超过100场的企业有27家&#xff0c;合计54850场&#xff0c;占比…

2023年中国骨质疏松治疗仪发展趋势分析:小型且智能将成为产品优化方向[图]

骨质疏松治疗仪利用磁场镇静止痛、消肿消炎的治疗作用迅速缓解患者腰背疼痛等骨质疏松临床症状。同时利用磁场的磁-电效应产生的感生电势和感生电流&#xff0c;改善骨的代谢和骨重建&#xff0c;通过抑制破骨细胞、促进成骨细胞的活性来阻止骨量丢失、提高骨密度。 骨质疏松治…

有能一键批量转换,轻松将PDF、图片转为Word/Excel的软件吗?

随着数字化时代的到来&#xff0c;OCR技术在我们的生活中变得越来越重要。无论是从图片中提取文字&#xff0c;还是将PDF、图片格式的文件转换为Word或Excel格式&#xff0c;OCR软件都能够为我们提供极大的便利。然而&#xff0c;市面上的OCR软件种类繁多&#xff0c;哪一款软件…

蓝桥杯第三周算法竞赛D题E题

发现更多计算机知识&#xff0c;欢迎访问Cr不是铬的个人网站 D迷宫逃脱 拿到题目一眼应该就能看出是可以用动态规划来解决。但是怎么定义dp呢? 这个题增加难度的点就在当所在位置与下一个要去的位置互质的时候&#xff0c;会消耗一把钥匙。当没有钥匙的时候就不能移动了。想…

802.11ax-2021协议学习__$27-HE-PHY__$27.5-Parameters-for-HE-MCSs

802.11ax-2021协议学习__$27-HE-PHY__$27.5-Parameters-for-HE-MCSs 27.3.7 Modulation and coding scheme (HE-MCSs)27.3.8 HE-SIG-B modulation and coding schemes (HE-SIG-B-MCSs)27.5 Parameters for HE-MCSs27.5.1 General27.5.2 HE-MCSs for 26-tone RU27.5.3 HE-MCSs f…

AE (1)_软件、硬件、驱动控制

#灵感# AE是个值得推敲再推敲的模块&#xff0c;有意思。 目录 相关的硬件-光圈&#xff1a; 相关的软件-曝光-ISO&#xff1a; ISP中的sensor AE 组成&#xff1a; sensor AE的流程及控制&#xff1a; 相关的硬件-光圈&#xff1a; 光圈&#xff08;F-Number&#xff0…

Equifax案例分析与合规性场景实践

在当今数字化时代&#xff0c;数据安全已经成为各个组织和企业亟待解决的问题。尤其是在数据泄露事件不断增多的背景下&#xff0c;保护敏感数据免受非法访问和泄露变得尤为紧迫。为了应对这一挑战&#xff0c;许多组织和企业开始利用密钥管理服务(KMS)来加强其数据安全性&…

KVM网络环境下vlan和trunk的理解

vmware exsi 平台&#xff0c;虚拟交换机管理界面的上行链路是什么意思 VMware ESXi中的虚拟交换机管理界面中的“上行链路”&#xff08;uplinks&#xff09;是指虚拟交换机连接到物理网络的物理网络适配器。在ESXi中&#xff0c;虚拟交换机&#xff08;vSwitch&#xff09;用…

Ubuntu18.04安装ROS系统+turtle测试

安装 1.设置安装源 sudo sh -c echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list sudo sh -c . /etc/lsb-release && echo "deb http://mirrors.tuna.tsinghua.edu.cn/ros/ubun…

4.1 Windows驱动开发:内核中进程与句柄互转

在内核开发中&#xff0c;经常需要进行进程和句柄之间的互相转换。进程通常由一个唯一的进程标识符&#xff08;PID&#xff09;来标识&#xff0c;而句柄是指对内核对象的引用。在Windows内核中&#xff0c;EProcess结构表示一个进程&#xff0c;而HANDLE是一个句柄。 为了实…

不允许你还不了解指针的那些事(二)(从入门到精通看这一篇就够了)(数组传参的本质+冒泡排序+数组指针+指针数组)

目录 数组名的理解 使用指针访问数组 一维数组传参的本质 冒泡排序 二级指针 指针数组 指针数组模拟二维数组 字符指针变量 数组指针变量 二维数组传参的本质 函数指针变量 函数指针变量的创建 函数指针变量的使用 两段有趣的代码 代码一 代码二 typedef关键字 函数指针数组 …

Saas+AI?这可能是2023年最精华的6篇文章

‍ 原文太长&#xff08;6篇总计40200字&#xff09;&#xff0c;我提炼出核心要点&#xff0c;并打散重组&#xff0c;最后总计仅4500字&#xff0c;不仅是节省了大家时间&#xff0c;还能带来更多不一样的视角解读。 文章一、「AI与SaaS结合的三部曲」 &#xff08;引自8月25…

计及源荷不确定性的综合能源生产单元运行调度与容量配置随机优化模型MATLAB

主要内容 本程序复现《计及源荷不确定性的综合能源生产单元运行调度与容量配置两阶段随机优化》模型&#xff0c;采用全年光伏、风电数据通过kmeans聚类得到6种场景&#xff0c;构建了随机优化模型&#xff0c;在研究融合P2G与CCS的IEPU系统框架基础上&#xff0c;建立了各关键…

JWT登录认证(3拦截器)

Jwt登录认证&#xff08;拦截器&#xff09;&#xff1a; 使用拦截器统一验证令牌 登录和注册接口需要放行 interceptors.LoginInterceptor&#xff1a;&#xff08;注册一个拦截器&#xff09; package com.lin.springboot01.interceptors;import com.lin.springboot01.pojo.…

设计模式-中介者模式-笔记

Medicator中介者模式 动机&#xff08;Motivation&#xff09; 在软件构建过程中&#xff0c;经常会出现多个对象相互关联交际的情况&#xff0c;对象之间常常会维持一种复杂的引用关系&#xff0c;如果遇到一些需求的更改&#xff0c;这种直接的引用关系将面临不断的变化。 …

电脑监控软,电脑屏幕监控软件

电脑监控软&#xff0c;电脑屏幕监控软件 电脑屏幕监控软件不仅仅是一种工具&#xff0c;更是一种守护。随着互联网的发展&#xff0c;我们工作越来越离不开电脑&#xff0c;但同时&#xff0c;也面临着更多的安全隐患。为了保护个人隐私&#xff0c;提高工作效率&#xff0c;…

Java基础笔记

1.数据类型在java语言中包括两种: 第一种:基本数据类型 基本数据类型又可以划分为4大类8小种: 第一类:整数型 byte , short,int, long(没有小数的&#xff09; 第二类:浮点型 float,aouble(带有小数的&#xff09; 第三类:布尔型 boole…

wpf devexpress在未束缚模式中生成Tree

TreeListControl 可以在未束缚模式中没有数据源时操作&#xff0c;这个教程示范如何在没有数据源时创建tree 在XAML生成tree 创建ProjectObject类实现数据对象显示在TreeListControl: public class ProjectObject {public string Name { get; set; }public string Executor {…

UE基础篇十:材质

导语: 视频文档在文末 虚幻引擎默认是延迟渲染(延迟渲染是通过先算出需要着色的像素,然后再迭代灯光,从而减少大量无效的灯光计算,来达到优化的目的) 一、基础知识 1.1 贴图分辨率尺寸 2的幂次方,长宽随意组合 非2的幂次方,不能设置MipMaps(引擎会生成多张分辨率更…