C++实用教程(四):面向对象核心多态 笔记

推荐B站视频:C++现代实用教程(四):面向对象核心多态_哔哩哔哩_bilibiliicon-default.png?t=N7T8https://www.bilibili.com/video/BV15v4y1M7fF/?spm_id_from=333.999.0.0&vd_source=a934d7fc6f47698a29dac90a922ba5a3

本项目通用的tasks.json文件和launch.json

  • tasks.json
{
    "version": "2.0.0",
    "options": {
        "cwd": "${workspaceFolder}/build"
    },
    "tasks": [
        {
            "type": "shell",
            "label": "cmake",
            "command": "cmake",
            "args": [
                ".."
            ]
        },
        {
            "label": "make",
            "group": "build",
            "command": "make",
            "args": [],
            "problemMatcher": []
        },
        {
            "label": "Build",
            "dependsOrder": "sequence",
            "dependsOn": [
                "cmake",
                "make"
            ]
        },
        {
            "type": "cppbuild",
            "label": "C/C++: g++ 生成活动文件",
            // "command": "/usr/bin/g++",
            "command": "D://mingw64//bin//g++.exe",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "-o",
                "${workspaceFolder}/bin/app.exe",
                // "-finput-charset=UTF-8",
                /*
                    -fexec-charset指定输入文件的编码格式
                    -finput-charset指定生成可执行的编码格式,
                */
                "-finput-charset=GBK",  // 处理mingw中文编码问题
                "-fexec-charset=GBK"
            ],
            "options": {
                "cwd": "${workspaceFolder}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "D://mingw64//bin//g++.exe"
        }
    ]
}
  • launch.json
{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) 启动",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/bin/app.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true,
                },
            ],
            "preLaunchTask": "Build",
            "miDebuggerPath": "D://mingw64//bin//gdb.exe", // 修改为你的 gdb 路径
        },
    ]
}
  • CMakeLists.txt
​cmake_minimum_required(VERSION 3.28.0)
project(project)
include_directories(${PROJECT_SOURCE_DIR}/include)
aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC_LIST)

add_executable(app main.cpp ${SRC_LIST})
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

​

C++的面向对象与很多其他的面向对象语言有很多不同,本质的原因是在于C++是一门极其重视性能的编程语言

>>多态是面向对象的核心

  • 这一点对于C++来说也不例外
  • 面向对象三大特性为:封装、继承、多态
    • 本人不是很喜欢C++的继承,其实是不喜欢继承
    • 封装和继承基本上是为多态而准备的
  • 面向对象是使用多态性获得对系统中每个源代码依赖项的绝对控制的能力的(大牛说的)
  • 高内聚、低耦合是程序设计的目标(无论是否面向对象,),而多态是实现高内聚,低耦合的基础

>>目录

    1.多态与静态绑定

    2.虚函数与动态绑定

    3.多态对象的应用场景与大小

    4.Override与Final

    5.Overloading与多态

    6.析构函数与多态

    7.Dynamic_cast类型转换

    8.typeid操作符

    9.纯虚函数与抽象类

    10.接口式抽象类

第一节:多态与静态绑定

>>多态:

  • 在编程语言和类型论中,多态(英语:polymorphism)指为不同数据类型的实体提供统一的接口
  • 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数

>>静态绑定:将名称绑定到一个固定的函数定义,然后在每次调用该名称时执行该定义,这个也是常态执行的方式

  • shape.h 
#ifndef SHAPE_H
#define SHAPE_H
#include <string>
#include <string_view>
#include <iostream>
class Shape{
public:
    Shape() = default;
    ~Shape() = default;
    Shape(std::string_view name);
    void draw() const {
        std::cout<<"Shape Drawing "<<m_name<<std::endl;
    }
protected:
    std::string m_name;
};
#endif
  • shape.cpp
#include "shape.h"

Shape::Shape(std::string_view name) : m_name(name){

}
  • rectangle.h
#ifndef RECTANGLE_H
#define RECTANGLE_H
#include <string>
#include <string_view>
#include <iostream>
#include "shape.h"
class Rectangle:public Shape{
public:
    Rectangle() = default;
    ~Rectangle() = default;
    Rectangle(double x,double y,std::string_view name);

    void draw() const {
        std::cout<<"Rectangle Drawing "<<m_name<<" with x: "<<get_x()<<",y: "<<get_y()<<std::endl;
    }
protected:
    double get_x() const{
        return m_x;
    }
    double get_y() const{
        return m_y;
    }
private:
    double m_x{0.0};
    double m_y{0.0};
};
#endif
  • rectangle.cpp
#include "rectangle.h"

Rectangle::Rectangle(double x, double y,std::string_view name)
    : Shape(name),m_x(x),m_y(y)
{

}
  • square.h
#ifndef SQUARE_H
#define SQUARE_H
#include "rectangle.h"
class Square:public Rectangle{
public:
    Square() = default;
    ~Square() = default;
    Square(double x,std::string_view name);

    void draw() const {
        std::cout<<"Square Drawing "<<m_name<<" with x: "<<get_x()<<std::endl;
    }
};
#endif
  • square.cpp
#include "square.h"

Square::Square(double x, std::string_view name)
    : Rectangle(x,x,name)
{
}
  • main.cpp
#include <iostream>
#include "square.h"
#include "rectangle.h"
#include "shape.h"
using namespace std;

// Shape -> Rectangle -> Square
// draw()
void test1() {
    // 静态绑定的不足
    Shape s1("Shape1");
    s1.draw();// Shape Drawing Shape1

    Rectangle r1(1.0,2.0,"Rectangle1");
    r1.draw();// Rectangle Drawing Rectangle1 with x: 1,y: 2

    Square sq1(3.0,"Square1");
    sq1.draw();// Square Drawing Square1 with x: 3

    // Base Pointer
    Shape* shape_ptr = &s1;
    shape_ptr->draw();// Shape Drawing Shape1
    shape_ptr = &r1;
    shape_ptr->draw();// Shape Drawing Rectangle1
    shape_ptr = &sq1;
    shape_ptr->draw();// Shape Drawing Square1
}

int main(int argc,char* argv[]) {
    test1();
    cout<<"over~"<<endl;
    return 0;
}
  •  执行结果:
PS D:\Work\C++UserLesson\cppenv\static_bind\build> ."D:/Work/C++UserLesson/cppenv/static_bind/bin/app.exe"
Shape Drawing Shape1
Rectangle Drawing Rectangle1 with x: 1,y: 2
Square Drawing Square1 with x: 3
Shape Drawing Shape1
Shape Drawing Rectangle1
Shape Drawing Square1
over~
PS D:\Work\C++UserLesson\cppenv\static_bind\build>



第二节:虚函数与动态绑定

>>动态绑定

  • 实现继承
  • 父类、子类需要动态绑定的函数设置为虚函数
  • 创建父类指针/引用(推荐指针)指向子类对象,然后调用

>>虚函数

  • 虚函数是应在派生类中重新定义的成员函数
  • 关键字为virtual

通过例子来实现多态

  • shape.h
#ifndef SHAPE_H
#define SHAPE_H
#include <string>
#include <string_view>
#include <iostream>
class Shape{
public:
    Shape() = default;
    ~Shape() = default;
    Shape(std::string_view name);
    virtual void draw() const {
        std::cout<<"Shape Drawing "<<m_name<<std::endl;
    }
protected:
    std::string m_name;
};
#endif
  • shape.cpp
#include "shape.h"

Shape::Shape(std::string_view name) : m_name(name){

}
  • rectangle.h
#ifndef RECTANGLE_H
#define RECTANGLE_H
#include <string>
#include <string_view>
#include <iostream>
#include "shape.h"
class Rectangle:public Shape{
public:
    Rectangle() = default;
    ~Rectangle() = default;
    Rectangle(double x,double y,std::string_view name);

    virtual void draw() const {
        std::cout<<"Rectangle Drawing "<<m_name<<","<<"x: "<<get_x()<<",y: "<<get_y()<<std::endl;
    }
protected:
    double get_x() const{
        return m_x;
    }
    double get_y() const{
        return m_y;
    }
private:
    double m_x{0.0};
    double m_y{0.0};
};
#endif
  • rectangle.cpp
#include "rectangle.h"

Rectangle::Rectangle(double x, double y,std::string_view name)
    : Shape(name),m_x(x),m_y(y)
{

}
  • square.h
#ifndef SQUARE_H
#define SQUARE_H
#include "rectangle.h"
class Square:public Rectangle{
public:
    Square() = default;
    ~Square() = default;
    Square(double x,std::string_view name);

    void draw() const {
        std::cout<<"Square Drawing "<<m_name<<" with x: "<<get_x()<<std::endl;
    }
};
#endif
  • square.cpp
#include "square.h"

Square::Square(double x, std::string_view name)
    : Rectangle(x,x,name)
{
}

执行结果:

PS D:\Work\C++UserLesson\cppenv\dynamic_bind\bin> ."D:/Work/C++UserLesson/cppenv/dynamic_bind/bin/app.exe"
Shape Drawing Shape1
Rectangle Drawing Rectangle1,x: 1,y: 2
Square Drawing Square1 with x: 3
over~
PS D:\Work\C++UserLesson\cppenv\dynamic_bind\bin>

未完待续~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【并发编程】 synchronized的普通方法,静态方法,锁对象,锁升级过程,可重入锁,非公平锁

目录 1.普通方法 2.静态方法 3.锁对象 4.锁升级过程 5.可重入的锁 6.不公平锁 非公平锁的 lock 方法&#xff1a; 1.普通方法 将synchronized修饰在普通同步方法&#xff0c;那么该锁的作用域是在当前实例对象范围内,也就是说对于 SyncDemosdnewSyncDemo();这一个实例对象…

基于Spring Boot的饮食分享平台设计与实现

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

springboot-mybatis项目

一、后端开发环境搭建 1、File->New->Projet 2选择 Spring Initializr &#xff0c;然后选择默认的 url 点击next 3勾选Spring Web、SQL模板&#xff0c;next 4点击finish&#xff0c;搭建完成 二 数据库 1 新建数据库 2 执行sql建表 SET NAMES utf8mb4; SET FOREIGN…

中移(苏州)软件技术有限公司面试问题与解答(4)—— virtio所创建的设备2

接前一篇文章&#xff1a;中移&#xff08;苏州&#xff09;软件技术有限公司面试问题与解答&#xff08;4&#xff09;—— virtio所创建的设备1 在上一篇文章中&#xff0c;对于面试所提出的问题“virtio会创建哪些设备&#xff1f;”&#xff0c;有了初步答案&#xff0c;即…

0125-1-vue3初体验

vue3尝鲜体验 初始化 安装vue/clinext&#xff1a; yarn global add vue/clinext # OR npm install -g vue/clinext然后在 Vue 项目运行&#xff1a; vue upgrade --next项目目录 vue3-template ├── index.html // html模板 ├── mock // mock数据 │ └── user.…

【前沿技术杂谈:NLP技术的发展与应用】探索自然语言处理的未来

【前沿技术杂谈&#xff1a;NLP技术的发展与应用】探索自然语言处理的未来 NLP技术的发展与应用&#xff1a;探索自然语言处理的未来方向一&#xff1a;技术进步词嵌入&#xff08;Word Embeddings&#xff09;Transformer架构自然语言推理 方向二&#xff1a;应用场景智能客服…

深入浅出 diffusion(2):pytorch 实现 diffusion 加噪过程

我在上篇博客深入浅出 diffusion&#xff08;1&#xff09;&#xff1a;白话 diffusion 原理&#xff08;无公式&#xff09;中介绍了 diffusion 的一些基本原理&#xff0c;其中谈到了 diffusion 的加噪过程&#xff0c;本文用pytorch 实现下到底是怎么加噪的。 import torch…

微软 Power Apps model drven app 模型驱动应用使用Plugin插件实现业务流程跳转阶段功能

微软 Power Apps model drven app 模型驱动应用使用Plugin插件实现业务流程跳转阶段功能 模型驱动应用使用插件实现跳转业务流程阶段跳转功能 在实际操作中总会遇到使用业务流程的需求&#xff0c;那么如何使用plugin实现跳转阶段的功能呢 需求背景是主表上有业务流程&#x…

解密Java并发中的秘密武器:LongAdder与Atomic类型

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 解密Java并发中的秘密武器&#xff1a;LongAdder与Atomic类型 前言引言&#xff1a;为何需要原子操作&#xff1f;挑战和问题&#xff1a;原子操作的概念和重要性&#xff1a; AtomicInteger和AtomicL…

leetcode hot100 组合总和Ⅲ

本题中&#xff0c;要求我们求在1-9范围内&#xff0c;满足k个数的和为n的组合&#xff08;组合是无序的&#xff0c;并且题目中要求不可以重复&#xff09;。 这种组合问题依旧需要用回溯算法来解决。因为我们没办法控制产生k层for循环。回溯算法的过程是构建树结构&#xff…

【并发编程】锁死的问题——如何解决?以及如何避免?

目录 1.如何解决 一、死锁的定义和原因 1.1 定义 1.2 原因 二、常见的死锁场景 2.1 线程间相互等待资源 2.2 嵌套锁的循环等待 2.3 对资源的有序请求 三、死锁排查的方法 3.1 使用jstack命令 3.2 使用jconsole 3.3 使用VisualVM 四、常见的解决方案 4.1 避免嵌套锁…

16、Kafka ------ SpringBoot 整合 Kafka (配置 Kafka 属性 及对应的 属性处理类 解析)

目录 配置 Kafka 及对应的 属性处理类配置KafkaKafka配置属性的约定代码演示生产者相关的配置消费者相关的配置 代码&#xff08;配置文件&#xff09;application.properties 配置 Kafka 及对应的 属性处理类 配置Kafka spring.kafka.* 开头的配置属性&#xff0c;这些属性将由…

【Vue2 + ElementUI】分页el-pagination 封装成公用组件

效果图 实现 &#xff08;1&#xff09;公共组件 <template><nav class"pagination-nav"><el-pagination class"page-area" size-change"handleSizeChange" current-change"handleCurrentChange":current-page"c…

ChatGPT模型大更新!全新大、小文本嵌入模型,API价格大降价!

1月26日凌晨&#xff0c;OpenAI在官网对ChatGPT Turbo模型&#xff08;修复懒惰行为&#xff09;&#xff0c;免费的审核模型&#xff0c;并对新的GPT-3.5 Turbo模型API进行了大幅度降价。模型进行了大更新&#xff0c;发布了两款全新大、小文本嵌入模型&#xff0c;全新的GPT-…

600条最强Linux命令总结,建议收藏

今天&#xff0c;带来一篇 Linux 命令总结的非常全的文章&#xff0c;也是我们平时工作中使用率非常高的操作命令&#xff0c;命令有点多&#xff0c;建议小伙伴们可以先收藏后阅读。 在此之前先给大家分享一波黑客学习资料 1. 基本命令 uname -m 显示机器的处理器架构 uname …

超级万能DIY模块化电商小程序源码系统 带完整的搭建教程

随着电商市场的不断扩大&#xff0c;越来越多的商家涌入电商平台&#xff0c;竞争愈发激烈。为了在众多竞争对手中脱颖而出&#xff0c;商家需要打造一款个性化、功能强大的电商小程序&#xff0c;以吸引更多的用户。而超级万能DIY模块化电商小程序源码系统正是为了满足商家的这…

第二证券:大金融板块逆势护盘 北向资金尾盘加速净流入

周一&#xff0c;A股商场低开低走&#xff0c;沪指收盘失守2800点。截至收盘&#xff0c;上证综指跌2.68%&#xff0c;报2756.34点&#xff1b;深证成指跌3.5%&#xff0c;报8479.55点&#xff1b;创业板指跌2.83%&#xff0c;报1666.88点。沪深两市合计成交额7941亿元&#xf…

基于Servlet实现博客系统

目录 一、功能和效果 1、实现的功能 2、页面效果 二、功能具体实现 1、数据库 &#xff08;1&#xff09;设计数据库 &#xff08;2&#xff09;创建数据库表 &#xff08;3&#xff09;实现对blogs表和users表的操作并封装 2、登陆功能实现 &#xff08;1&#xff09…

筑梦前行!苏州金龙荣获影响中国客车业两项大奖

2024年1月19日&#xff0c;第十八届影响客车业年度盘点颁奖典礼在合肥举行。活动期间&#xff0c;众多奖项如期揭晓&#xff0c;经组委会评审团评定&#xff0c;苏州金龙海格睿星KLQ5041XSWEV1、旅行家KLQ6127YEV1N分别荣获“定制旅游客车之星”大奖和“新能源客车推荐车型”大…

搜索引擎Elasticsearch了解

1.Lucene 是什么? 2.模块介绍 Lucene是什么: 一种高性能,可伸缩的信息搜索(IR)库 在2000年开源,最初由鼎鼎大名的Doug Cutting开发 是基于Java实现的高性能的开源项目 Lucene采用了基于倒排表的设计原理,可以非常高效地实现文本查找,在底层采用了分段的存储模式,使它在读…