第十九章:特殊工具与技术

第十九章:特殊工具与技术

对于很多程序员来说,他们很少会用到本章的介绍的内容。

一.控制内存分配

我们能够重载new和delete,但其实不是对new和delete的重载,只是对new和delete操作符后面的函数进行重载。

当我们使用一条new表达式的时候,第一步new表达式调用一个名为operator new或operator new [] 的函数分配内存空间。第二步,编译器运行构造函数构造对象并传入初始值,第三步,返回一个指向该对象的指针。

当我们使用一条delete表达式的时候,第一步执行析构函数,第二步调用operator delete或operator delete []释放内存空间。

如果希望控制内存分配的过程,可以定义自己的operator new函数和operator delete函数。可以在全局作用域中定义这两个函数,也可以定义为成员函数。当编译器发现一条new或delete表达式时且对象是类类型,则先在类和基类的作用域中找这两个函数。当我们定义为成员函数时,这两类函数是隐式静态的。因为operator new用在对象构造之前,operator delete用在对象析构之后,所以必须是静态的且不能使用类的任何数据成员。

要实现这两类函数,可以使用malloc和free。

二.运行时内存识别

运行时内存识别的功能由两个运算符实现:typeid:用于返回表达式的类型;dynamic_cast:用于将基类的指针或引用安全的转换成派生类的指针或引用。

RTTI可以让我们在不能使用虚函数的情况下实现多态。

typeid操作的结果是一个常量对象的引用,该对象的类型是标准库类型type_info或type_info的公有派生类型。

当typeid作用于指针时(而非指针所指的对象),返回的结果是该指针的静态编译类型。

如果表达式的动态类型和静态类型不同,typeid会在运行时对表达式求值以确定返回的类型。

三.枚举类型

枚举类型使我们可以将一组整形常量组织在一起。每个枚举类型定义了一种新的类型,枚举属于字面值常量类型。

C++包含两种枚举:限定作用域和不限定作用域的。限定作用域是C++11新标准引入的,定义方式为在定义的时候在enum后面加上class或struct。

在限定作用域的枚举类型中,枚举成员的名字遵循常规的作用域准则,并且在枚举类型的作用域外是不可访问的(可以用作用域运算符访问);在不限定作用域的枚举类型中,枚举成员的作用域与枚举类型本身的作用域相同。

默认情况下,枚举值从0开始,依次加1,不过我们也能为一个或几个枚举成员指定专门的值。枚举值不一定唯一。枚举成员是const的。

enum是由某种整型类型表示的,在C++11新标准中,我们可以在enum的名字后加上冒号以及我们想在该enum中使用的类型。如果不加,限定的默认是int,非限定的默认不知。

四.类成员指针

成员指针是指可以指向类的非静态成员的指针。一般情况下指针指向一个对象,但是成员指针指向的是类的成员,而不是某个特定对象。

成员指针的类型囊括了类的类型及成员的类型。当初始化一个这样的指针时,我们令其指向类的某个成员,但是不指定该成员所属的对象;直到使用成员指针时,才提供成员所属的对象。

常规的访问控制规则对成员指针同样有效。

五.嵌套类

一个类可以定义在另一个类的内部,前者称为嵌套类或嵌套类型。

嵌套类和外部类没有什么特别的关系,只是嵌套类位于外部类的作用域中,受外部类的访问控制,两者都不含对方的成员。

六.union:一种节省空间的类

联合(union)是一种特殊的类。可以有多个数据成员,但是在任意时刻只有一个数据成员可以有值。分配给一个union对象的存储空间至少要能容纳它的最大成员。union可以为其成员指定public,protected和private等标记,默认为public。可以定义包括构造函数和析构函数在内的成员函数,不能定义虚函数。

匿名union是一个未命名的union,并且在右花括号和分号之间没有任何生命。一旦我们定义了一个匿名union,编译器就会自动为该union生成一个未命名的对象,在匿名union所在的作用域内该union的成员都是可以直接访问的。

对于union来说,要想构造或销毁类类型的成员必须执行非常复杂的操作,因此我们通常把含有类类型成员的union内嵌在另一个类中。这个类可以管理并控制与union的类类型成员有关的状态转换。

七.局部类

类可以定义在函数的内部,我们称这样的类为局部类。局部类定义的类型只在定义它的作用域可见。局部类的所有成员(函数在内)都必须完成定义在类的内部。局部类不允许声明静态成员。

局部类只能访问外层作用域定义的类型名、静态变量以及枚举成员。

八.固有的不可移植的特性

为了支持低层编程,C++定义了一些固有的不可移植的特性。所谓不可移植是指因机器而异。

类可以将其非静态成员定义为位域,在一个位域中含有一定数量的二进制位。当一个程序需要向其他程序或硬件设备传递而二进制数据时,通常会用到位域。

位域在内存中的布局是与机器相关的。

位域的类型必须是整型或枚举类型。通常是无符号类型。位域的声明形式是在成员名字之后紧跟一个冒号以及一个常量表达式,该表达式用于指定成员所占的二进制位数。

取地址运算符不能作用于位域,因此任何指针都无法指向类的位域。

当对象的值可能在程序的控制或检测之外被改变时,应该将该对象声明为volatile。关键字volatile告诉编译器不应对这样的对象进行优化。

volatile的确切含义与机器有关,只能通过阅读编译器文档来理解。

就像一个类可以定义const成员函数一样,它也能将成员函数定义为volatile的。只能volatile的成员函数才能被volatile的对象调用。

和const一样,我们只能将一个volatile对象的地址赋给一个指向volatile的指针。对引用也一样。

我们不能使用合成的拷贝/移动函数及赋值运算符初始化volatile。

C++使用链接指示指出任意非C++函数所用的语言。

对于使用链接指示定义的函数来说,它的每个声明都必须使用相同的链接指示,指向其他语言编写的函数的指针必须与函数本身使用相同的链接指示。

指向C函数的指针和指向C++函数的指针是不一样的类型,不能混用。

当我们使用链接指示时,它不仅对函数有效,而且对作为返回类型或形参类型的函数指针也有效(即若它的形参或返回类型是函数指针的话,则也是那种语言的函数指针)。所以如果我们希望给C++函数传入一个指向C函数的指针,则必须使用类型别名。

有时需要在C和C++中编译同一个源文件,为了实现这一目的,在编译C++版本的程序时预处理器定义__cplusplus。利用这个变量,我们可以在编译C++程序的时候有条件地包含进来一些代码。

完结撒花!!!🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉

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

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

相关文章

【Maven笔记3】Maven基础入门案例

本篇通过一个最基础的入门案例,熟悉一下maven最基础的使用方法。 编写POM maven项目的核心是pom.xml文件,pom定义了项目的基本信息,用于描述项目如何构建,声明项目依赖等等。 这里我们新建一个maven-demo-hello项目,…

【用队列实现栈】【用栈实现队列】Leetcode 232 225

【用队列实现栈】【用栈实现队列】Leetcode 232 225 队列的相关操作栈的相关操作用队列实现栈用栈实现队列 ---------------🎈🎈题目链接 用队列实现栈🎈🎈------------------- ---------------🎈🎈题目链…

What is `ResponseEntity` does?

Further Reading : What does ResponseEntity do?

【Spring Boot 3】【数据源】自定义多数据源

【Spring Boot 3】【数据源】自定义多数据源 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是…

如何引用R语言版本以及R包版本

在分析数据时,我们需要引用R语言的特定版本,以及使用R包的版本,其实R语言中有代码可以调用,下面介绍一下。 1,引用R语言 在R语言中键入: citation()结果: > citation()To cite R in publ…

TCP 的三次握手和四次挥手

Java 面试题 TCP 三次握手 第一次握手:客户端向服务端发送SYN包。报文中标志位SYN1,序列号seqx(x为随机整数)。此时客户端进入了 SYN_SEND 同步已发送状态。 第二次握手:服务端回复客户端SYNACK包。报文中标志位SYN1&…

用Python制作一个网站来介绍bicart

本文使用创作助手。 下面是一个使用Flask框架制作的bicart介绍网站的示例,其中包括美观的界面、背景颜色和背景音乐,以及图片轮播、描点、登录和注册功能。 from flask import Flask, render_template, request, redirect, url_for, sessionapp Flask…

宿舍管理系统的设计与实现:基于Spring Boot、Java、Vue.js和MySQL的完整解决方案

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

双向链表的构建

上篇内容给大家带来了单链表的构建,那么本期内容继续给大家带来链表的相关内容----双向链表。 什么是双向链表?双向链表与单链表有什么区别? 在单链表中,咱们每个结点的指针域存放了后继指针,以便于链接每个结点&…

文理导航期刊投稿方式

《文理导航》杂志系国家新闻出版总署批准,内蒙古自治区文旅厅主管,内蒙古自治区北方文化研究院主办的,面向大中专院校、中小学教育的专业性教育刊物,阅读对象是关心教育事业发展的大中专院校、职业教育、中小学教育的专家、教研员…

大学生个性化旅游网站的设计与实现

大学生个性化旅游网站的设计与实现 摘要 如今的互联网技术也很成熟,原来生活中的很多线下服务也在逐渐的转型,传统线下旅游服务已经逐渐转变为线上旅游服务,现代新型线上旅游服务和之前的线下传统服务的不同之处在于线上服务是双向交流的&a…

01-k8s学习笔记之认识 Kubernetes

1、什么是 Kubernetes? Kubernetes 是一个开源的,用于管理云平台中多个主机上的容器化的应用, Kubernetes 的目标是让部署容器化的应用简单并且高效(powerful), Kubernetes 提供了应用部署,规划…

Flask框架小程序后端分离开发学习笔记《1》网络知识

Flask框架小程序后端分离开发学习笔记《1》网络知识 Flask是使用python的后端,由于小程序需要后端开发,遂学习一下后端开发。 一、网址组成介绍 协议:http,https (https是加密的http)主机:g.cn zhihu.com之类的网址…

IP定位API接口:省、市、城市的adcode编码、所在城市矩形区域范围(VIP版)

IP定位API接口:省、市、城市的名称和adcode编码、所在城市矩形区域范围 本文提供一个IP定位查询接口:省、市、城市的名称adcode编码,并返回一个参考坐标本接口是收费的(1分钱1次调用,免费的跳转链接查看,也…

嵌入式-Stm32-江科大基于寄存器点亮LED灯

文章目录 前言:一:搭建基于寄存器控制LED的工程二:用江科大的STM32板子实现基于寄存器点亮LED灯三:用非江科大stm32板子实现基于寄存器点亮LED灯道友:一星陨落,黯淡不了星空灿烂;一花凋零&#…

Flume 之自定义 Source

1、简介 Flume 自带 Source 有 Avro、Thrift、Netcat、Taildir、Kafka、Http等,有些场合比如我们指定访问接口获取数据当做 Flume 的 Source,像这种定制化的 Source 需要我们自己实现,下面我将介绍如何自定义实现 Source。 2、自定义实现 Fl…

Git 是什么?

Git 是什么? Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 Git 与常用的版本控制工具 CVS, Subversion 等不同,…

Cesium 模型压平

最近整理了下手上的代码,以下是对模型压平的说明。 原理是使用了customShader来重新设置了模型的着色器,通过修改模型顶点的坐标来实现了压平。 废话不多说,下面上代码: /*** class* description 3dtiles模型压平*/ class Flat…

推荐给前端程序员的5款浏览器插件

所谓“工欲善其事,必先利其器”。Chrome(谷歌浏览器) 应该是程序员或者互联网行业人员使用最多的浏览器了。而在日常开发中,下面几款 浏览器 扩展也许能让你的开发工作事半功倍 。 1、Vimium vimium 是一个旨在将你的双手从鼠标…

【力扣·每日一题】2645. 构造有效字符串的最小插入数(动态规划 贪心 滚动数组优化 C++ Go)

题目链接 题意 给你一个字符串 word &#xff0c;你可以向其中任何位置插入 “a”、“b” 或 “c” 任意次&#xff0c;返回使 word 有效 需要插入的最少字母数。 如果字符串可以由 “abc” 串联多次得到&#xff0c;则认为该字符串 有效 。 提示&#xff1a; 1 < w o r…