C++ 抽象机制

抽象机制

1. 虚函数 使用关键字virtual 声明的函数,意思是可能随后在其派生类中重新定义。

纯虚函数 在声明的末尾使用=0 的函数,说明是纯虚函数。

抽象类 含有纯虚函数多的类称为抽象类(abstract class).

多态类型 如果一个类负责为其他一些类提供接口,前面一个类被称为多态类型。

虚函数是如何解析到正确的执行函数呢?

采用的是虚函数表vtbl:
一般编译器将虚函数的名字转换成函数指针表中对应的索引值

class Vector {
private:double* elem;int sz;
public:Vector(int s) : elem{new double[s]}, sz{s} {}~Vector() {delete [] elem;};double& operator[](int i) {return elem[i];}int size() const {return sz;}};
class EmplyClass {};
class Container {// Vector v;
public:void function() {}
};class VirtualContainer{// Vector v;
public:virtual ~VirtualContainer(){}virtual void virtualFunction() = 0;
};class SubContainer : public VirtualContainer {
public:virtual ~SubContainer(){}void virtualFunction() override {}
};class SubContainer2 : public Container {};
int main(int argc, char **argv) {SubContainer con;SubContainer2 con2;EmplyClass c;std::cout << "SubContainer size: " <<sizeof(con)/sizeof(char) <<  std::endl;std::cout << "SubContainer2 size: " <<sizeof(con2)/sizeof(char) <<  std::endl;std::cout << "EmplyClass size: " <<sizeof(c) <<  std::endl;std::cout << "Version " << chapter3_VERSION_MAJOR << "." << chapter3_VERSION_MINOR << std::endl;return 0;
}

运行结果为:

SubContainer size: 8
SubContainer2 size: 1
EmplyClass size: 1
Version 0.1

对于con(SubContainer) , 继承自类VirtualContainer(抽象类), 存在一个vtbl 指针,如下图:
在64位操作系统中指针占8个byte.

在这里插入图片描述

对于con2(SubContainer2), 继承自Container(非抽象类),其中没有, 如下图:
占用1个byte.

而对于一个空的类型EmptyClass 对象, 如下图:
占用1byte.

在这里插入图片描述

  • What is empty class ?
    Empty class: It is a class that does not contain any data members (e.g. int a, float b, char c, and string d, etc.) However, an empty class may contain member functions.
    对于继承自非抽象类的子类和一个空实体类,占用1个byte. Why is the Size of an Empty Class Not Zero in C++?

When the structure was introduced in C, there was no concept of Objects at that time. So, according to the C standard, it was decided to keep the size of the empty structure to zero.

In C++, the Size of an empty structure/class is one byte as to call a function at least empty structure/class should have some size (minimum 1 byte is required ) i.e. one byte to make them distinguishable.

  • 如果类包含虚函数,则该类的对象需要一个额外的指针;另外对于这样的类需要一个vtbl.

基类的析构函数

如果基类不提供析构函数,或者析构函数不是虚函数, 在使用抽象基类的接口操纵时,子类的析构函数会无法访问;
如果基类的析构函数是虚函数,则子类的析构函数会覆盖它。当使用基类的接口操纵派生类时,才能确保调用到正确的析构函数。

class VirtualContainer{// Vector v;
public:/*(1)*/virtual ~VirtualContainer() {std::cout << "VirtualContainer release: " <<  std::endl;}// virtual ~VirtualContainer(){}virtual void virtualFunction() = 0;
};
class SubContainer : public VirtualContainer {
public:~SubContainer() {std::cout<< "SubContainner release" << std::endl;}
// virtual ~SubContainer(){}void virtualFunction() override {}
};// 当以如下方式使用时:VirtualContainer* baseContainer = new SubContainer();delete baseContainer;// 在此处析构 baseContainer 时, 如果没有(1) 的声明,~SubContainer() 将不会被调用

拷贝和移动

  • 默认情况下,拷贝的默认含义是逐成员复制。 逐成员复制通常符合拷贝操作的本来语义,对于像vector 或者抽象类型 是不正确的。

拷贝容器

类对象的拷贝操作可以通过两个成员来定义:拷贝构造函数和拷贝复制函数

Vector(const Vector& a); // 拷贝构造函数
Vector& operator=(const Vector& a); // 拷贝运算符Vector::Vector(const Vector& a):elem(new double[sz]),sz(a.sz)
{for (int i = 0; i < a.sz; i++) {elem[i] = a.elem[i];}
}Vector& Vector::operator=(const Vector& a) {double *p = new double[a.sz];for (int i = 0; i < a.sz; i++) {p[i] = a.elem[i];}delete[] elem;elem = p;sz = a.sz;return *this;
}

移动容器

  • 对于大的容器而言,拷贝过程耗费巨大(可能是时间或者空间上的耗费)
 声明:/** 移动构造函数*/Vector(Vector&& a);/** 移动赋值运算符*/Vector& operator=(Vector&& a);
实现:
Vector::Vector(Vector&& a):elem(a.elem),sz(a.sz)
{std::cout << "移动构造函数被调用" << std::endl;a.elem = nullptr;a.sz = 0;
}Vector& Vector::operator=(Vector&& a) {std::cout << "移动赋值运算符被调用" << std::endl;if (this != &a) {this->elem = a.elem;this->sz = a.sz;}a.elem = nullptr;a.sz = 0;return *this;
}
  • 左值: 能出现在赋值运算符的左侧的内容
  • 右值: 无法为其赋值的值
  • && 右值引用
  • 移动构造函数不接受(const实参, 因为移动构造函数会删除实参中的值,如果放了const 则无法删除)
  • 使用移动构造函数或拷贝构造的场合

资源管理

  • 可以把指针转化为资源句柄,比如使用智能指针(如unique_ptr)实现强资源安全,对于一般概念上的资源可以消除资源泄漏。

抑制操作

虽然类中可能未定义拷贝构造或者移动构造函数等,但是当代码中存在拷贝或者移动的操作情况下,编译器会自动生成相应的构造函数或者赋值函数。
对于部分实现类,使用默认的拷贝构造函数或移动操作常常意味着风险。对于不需要或者不能移动或者复制的类,最好是删除默认的拷贝和移动操作。

形式大致如下:

Shape(const Shape&) = delete;  // 没有拷贝操作
Shape& operator=(const Shape&) = delete;Shape(Shape&& ) = delete;  // 没有移动操作
Shape& operator=(Shape&& )= delete;

模板

  • 模板: 一个模板(template)就是一个类或一个函数,但是需要我们用一组类型或者值对其进行参数化。
  • 使用模板表示那些通用的概念,通过指定实参,生成特定的类型或者函数。

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

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

相关文章

【Camera KMD ISP SubSystem笔记】CAM SYNC与DRQ②

DRQ的作用&#xff1a; DRQ负责调度管理pipeline里的node处理逻辑(通过node之间的dependency依赖机制) 利用多线程并行处理Pipeline中并行的node&#xff0c;加快处理速度 DRQ运转流程&#xff1a; DRQ先告诉node fill dependency&#xff0c; 此时seq id 为0…

RakSmart站群服务器租用注意事项科普

随着互联网的飞速发展&#xff0c;站群运营成为越来越多企业和个人的选择。而RakSmart作为知名的服务器提供商&#xff0c;其站群服务器租用服务备受关注。在租用RakSmart站群服务器时&#xff0c;源库建议有一些关键的注意事项需要特别留意&#xff0c;以确保服务器的稳定运行…

springboot 集成 flowable

随着企业对于业务流程管理需求的增加&#xff0c;流程引擎在企业信息化建设中的作用越来越重要。Flowable是一个开源的轻量级业务流程管理&#xff08;BPM&#xff09;和工作流引擎&#xff0c;它支持BPMN 2.0标准。 Flowable的一些特点&#xff1a; 安装集成&#xff1a;Flow…

记一次生产事故的排查和解决

一. 事故概述 春节期间, 生产系统多次出现假死不可用现象, 导致绝大部分业务无法进行. 主要表现现象为接口无法访问. 背景为900W客户表和近实时ES, 以及春节期间疫情导致的普通卖菜场景近似秒杀等. 二. 排查过程 优先排查了info, error, catalina日志, 发现以下异常: 主要的…

【漏洞复现】IP-guard WebServer 权限绕过漏洞

0x01 产品简介 IP-guard WebServer 是 IP-guard 网络安全管理系统的一部分,用于提供 Web 界面以进行用户权限管理、监控和审计。 0x02 漏洞概述 IP-guard WebServer的权限验证机制中存在设计缺陷,未授权的攻击者能够规避安全验证,通过后端接口执行文件的任意读取和删除操…

每天五分钟深度学习:导数是反向传播算法的数学基础

本文重点 导数作为微积分学的核心概念之一,不仅在数学领域内占有举足轻重的地位,更在实际问题中发挥着不可替代的作用。我们要想学习反现象传播算法,我们前提是先要学习导数的概念。本节课程我们将看一下导数是什么? 导数 导数,顾名思义,是函数在某一点或某一段区间内…

使用PyCharm开发工具创建工程

一. 简介 前面文章实现了开发 python程序使用的 开发工具PyCharm&#xff0c;本文来学习使用 PyCharm开发工具创建一个 python工程。 二. 使用PyCharm开发工具创建工程 1. 首先&#xff0c;打开 PyCharm开发工具&#xff0c;打开 "New project" 选项&#xff1a; …

opencv_23_高斯模糊

void ColorInvert::gaussian_blur(Mat& image) { Mat dst; GaussianBlur(image, dst, Size(0, 0), 15); // Size(2, 2), imshow("图像模糊2", dst); }

【AIGC调研系列】LLaVA++整合Phi-3和Llama-3能够实现什么

LLaVA能够为Phi-3和Llama-3带来的主要好处包括&#xff1a; 视觉处理能力的增强&#xff1a;通过整合Phi-3和Llama-3模型&#xff0c;创建了具备视觉处理能力的Phi-3-V和Llama-3-V版本&#xff0c;这意味着这些模型现在能够理解和生成与图像相关的内容[1]。这种能力的增加&…

Golang错误处理机制

文章目录 Golang错误处理机制panic异常recover捕获异常自定义错误 Golang错误处理机制 panic异常 panic异常 Go的类型系统会在编译时捕获很多错误&#xff0c;但有些错误只能在运行时检查&#xff0c;比如除零错误、数组访问越界、空指针引用等&#xff0c;这些运行时错误会引…

springboot-异步、定时、邮件任务

目录 一&#xff0c;前言 二&#xff0c;异步 2.1&#xff0c;案例&#xff1a; 1&#xff0c;首先创建一个service&#xff1a; 2&#xff0c;Controller: ① 想办法告诉spring我们的异步方法是异步的&#xff0c;所以要在方法上添加注解 Async ②去springboot主程序中开…

可以在手机端运行的大模型标杆:微软发布第三代Phi-3系列模型,评测结果超过同等参数规模水平,包含三个版本,最小38亿,最高140亿参数

本文原文来自DataLearnerAI官方网站&#xff1a; 可以在手机端运行的大模型标杆&#xff1a;微软发布第三代Phi-3系列模型&#xff0c;评测结果超过同等参数规模水平&#xff0c;包含三个版本&#xff0c;最小38亿&#xff0c;最高140亿参数 | 数据学习者官方网站(Datalearner…

CH4INRULZ-v1靶机练习实践报告

CH4INRULZ-v1靶机练习实践报告 1 安装靶机 靶机是.ova文件&#xff0c;需要用VirtualBox打开&#xff0c;但我习惯于使用VMWare,因此修改靶机文件&#xff0c;使其适用于VMWare打开。 解压ova文件&#xff0c;得到.ovf文件和.vmdk文件。直接用VMWare打开.ovf文件即可。 2 夺…

【Unity动画系统】Animator组件的属性

介绍Animator组件的全部属性 Controller&#xff1a;动画控制器 Avatar&#xff1a;人物骨骼 Apply Root Motion&#xff1a;有一些动画片段自带位移&#xff0c;如果希望自带的位移应用在游戏对象上&#xff0c;那么就勾选&#xff1b;如果自己编写脚本&#xff0c;那么就不…

Xcode 15构建问题

构建时出现的异常&#xff1a; 解决方式&#xff1a; 将ENABLE_USER_SCRIPT_SANDBOXING设为“no”即可&#xff01;

stm32 hid自定义接收发送程序开发过程记录

cubleMX配置如下 修改端点描述符一次传输的数据大小 根据cubelMX标准在这里修改 编译错误 直接修改&#xff08;因为没有使用nodef &#xff09;编译通过 修改报告描述符&#xff08;默认的描述符无法传输数据&#xff09; 参考&#xff1a;USB协议详解第10讲&#xff08;USB描…

Web 渗透测试神器:HackBar 保姆级教程

一、介绍 HackBar 是一个用于浏览器的扩展插件&#xff0c;主要用于进行网络渗透测试和安全评估。它提供了一系列方便的工具和功能&#xff0c;可以帮助用户执行各种网络攻击和测试&#xff0c;包括 XSS、SQL 注入、CSRF、路径穿越等。以下是 HackBar 插件的一些主要特点和功能…

Java使用SpringBoot和EasyExcel 实现动态数据导出实战

Java使用SpringBoot和EasyExcel 实现动态数据导出实战 1、前言2、【资源地址】3、代码示例(demo)4、目前Java实现数据导出为Excel方式5、依赖6、总结 1、前言 工作中有用到将数据导出为Excel的场景&#xff0c;在此记录下。在日常开发中&#xff0c;Excel文件处理是一项常见的…

【VSCode调试技巧】Pytorch分布式训练调试

最近遇到个头疼的问题&#xff0c;对于单机多卡的训练脚本&#xff0c;不知道如何使用VSCode进行Debug。 解决方案&#xff1a; 1、找到控制分布式训练的启动脚本&#xff0c;在自己的虚拟环境的/lib/python3.9/site-packages/torch/distributed/launch.py中 2、配置launch.…

【网络安全】HTTP协议 — 基础

专栏文章索引&#xff1a;网络安全 有问题可私聊&#xff1a;QQ&#xff1a;3375119339 目录 学习目标​ 一、万维网的诞生与发展​编辑 1.万维网的诞生与发展 2.HTTP协议诞生与发展 二、网络基础 1.TCP/IP分层传输 1&#xff09;TCP/IP协议 2&#xff09;封装与拆封 …