C++常用的特性-->day05

友元的拓展语法

声明一个类为另外一个类的友元时,不再需要使用class关键字,并且还可以使用类的别名(使用 typedef 或者 using 定义)。

#include <iostream>
using namespace std;// 类声明
class Tom;
// 定义别名
using Honey = Tom;// 定义两个测试类
class Jack
{// 声明友元// friend class Tom;    // C++98 标准语法friend Tom;             // C++11 标准语法 string name = "jack";   // 默认私有void print()            // 默认私有{cout << "my name is " << name << endl;}
};class Lucy
{
protected:// 声明友元// friend class Tom;    // C++98 标准语法friend Honey;           // C++11 标准语法 string name = "lucy";void print(){cout << "my name is " << name << endl;}
};class Tom
{
public:void print(){// 通过类成员对象访问其私有成员cout << "invoke Jack private member: " << jObj.name << endl;cout << "invoke Jack private function: " << endl;jObj.print();cout << "invoke Lucy private member: " << lObj.name << endl;cout << "invoke Lucy private function: " << endl;lObj.print();}
private:string name = "tom";Jack jObj;Lucy lObj;
};int main()
{Tom t;t.print();return 0;
}

在这里插入图片描述

类模板的友元应用

在c++98时不可以为类模板声明友元,c++11新特性是可以声明为友元的

基本用法

class Tom;template<typename T>
class Person
{friend T;
};int main()
{Person<Tom> p;// >>>>>>>>>> Tom类是Person类的友元Person<int> pp;// >>>>>>>>>>> 对于int类型的模板参数,友元声明被忽略(第6行)return 0;
}

复杂案例

#include<iostream>
using namespace std;
template<typename T>
class Rectangle
{
public:friend T;Rectangle(int w, int h) : width(w), height(h) {}
private:int width;int height;
};template<typename T>
class Circle
{
public:friend T;Circle(int r) : radius(r) {}
private:int radius;
};// 校验类
class Verify
{
public:void verifyRectangle(int w, int h, Rectangle<Verify>& r){if (r.width >= w && r.height >= h){cout << "矩形的宽度和高度满足条件!" << endl;}else{cout << "矩形的宽度和高度不满足条件!" << endl;}}void verifyCircle(int r, Circle<Verify>& c){if (r >= c.radius){cout << "圆形的半径满足条件!" << endl;}else{cout << "圆形的半径不满足条件!" << endl;}}
};int main()
{Verify v;Circle<Verify> circle(30);Rectangle<Verify> rect(90, 100);v.verifyCircle(60, circle);v.verifyRectangle(100, 100, rect);return 0;
}

在这里插入图片描述

强类型枚举

枚举的缺陷

// 匿名枚举
enum {Red, Green, Blue};
// 有名枚举
enum Colors{Red, Green, Blue};

如果这个时候在main函数下执行:

cout<<"red:"<<red<<endl;//err 属于重定义

错误的原因:在这两个枚举中Red是全局可见的,所有编译器就会提示其重定义了。

强类型枚举语法

针对枚举的缺陷,C++11标准引入了一种新的枚举类型,即枚举类,又称强类型枚举(strong-typed enum)。
声明强类型枚举非常简单,只需要在 enum 后加上关键字 class

强类型枚举特性

  • 强作用域,强类型枚举成员的名称不会被输出到其父作用域空间。
  • 强类型枚举只能是有名枚举,如果是匿名枚举会导致枚举值无法使用(因为没有作用域名称)。
    转换限制,强类型枚举成员的值不可以与整型隐式地相互转换
  • 可以指定底层类型。强类型枚举默认的底层类型为 int,但也可以显式地指定底层类型
    具体方法为在枚举名称后面加上∶type,其中 type 可以是除 wchar_t 以外的任何整型。比如:
#include<iostream>
using namespace std;enum class Color:char{ Red, Green, Blue };
enum struct Color1 { Red, Green, Blue };int main()
{cout << "red:" << (int)Color::Red << endl;int m = (int)Color::Green;cout << "green:" << (int)Color::Green << endl;cout << "sizeof Color:char" << sizeof(Color) << endl;cout << "sizeof Color1:" << sizeof(Color1) << endl;return 0;
}

在这里插入图片描述

对原有枚举的拓展

原有枚举类型的底层类型在默认情况下,仍然由编译器来具体指定实现。但也可以跟强类型枚举类一样,显式地由程序员来指定。其指定的方式跟强类型枚举一样,都是枚举名称后面加上∶type,其中type 可以是除 wchar_t 以外的任何整型

#include<iostream>
using namespace std;enum TestColor:char { Red='a', Green, Blue };//>>>>>>普通枚举是可以直接访问的enum class Color:char{ Red, Green, Blue };
enum struct Color1 { Red, Green, Blue };int main()
{cout << "TestColor Red:" << Red << endl<< "TestColor Red:" << TestColor::Red << endl;cout << "sizeof TestColor:" << sizeof(TestColor) << endl;cout << "Red:" << (int)Color::Red << endl;int m = (int)Color::Green;cout << "green:" << (int)Color::Green << endl;cout << "sizeof Color:char" << sizeof(Color) << endl;cout << "sizeof Color1:" << sizeof(Color1) << endl;return 0;
}

在这里插入图片描述

非受限联合体

静态类型的数据/成员在非受限联合体的使用

在c++11里面不受限的是:静态类型的成员、POD类型
对于引用还是受限制的

#include<iostream>
using namespace std;union Test
{int age;long id;// int& tmp = age; // error >>>>>>>>> 非受限联合体中不允许出现引用类型static char c;static int print(){cout << "c value: " << c << endl;return 0;}
};
char Test::c;
// char Test::c = 'a';int main()
{Test t;Test t1;t.c = 'b';t1.c = 'c';t1.age = 666;cout << "t.c: " << t.c << endl;cout << "t1.c: " << t1.c << endl;//在联合体中,所有成员共享相同的内存空间。所以,当你给某个成员赋值时,其他成员的值也会被改变// //在非受限联合体中静态成员变量和非静态成员变量使用的不是同一块内存cout << "t1.age: " << t1.age << endl;cout << "t1.id: " << t1.id << endl;t.print();Test::print();return 0;
}

在这里插入图片描述

POD类型在非受限联合体的使用

union Student 中包含了一个 string 类型成员,而 std::string 是一个复杂的类类型,具有构造函数、析构函数和其他成员函数。由于 string 类型的存在,Student 联合体不能被视为 POD 类型。

如果原本类中的是POD类型,如果这个时候添加了一段自定义的构造函数那么此时的类就不是POD类型

union Student
{int id;string name;
};int main()
{Student s;//errreturn 0;
}

由于非POD类型在非受限联合体的使用,这个联合体的构造函数就会被删除。

解决方案:手动地去指定一块内存空间

即–>使用placement new

placement new

  • 使用new申请内存空间:Base* ptr = new Base;
  • 使用定位放置new申请内存空间:
    ClassName* ptr = new (定位的内存地址)ClassName;
简单案例
#include <iostream>
using namespace std;class Base
{
public:Base() {}~Base() {}void print(){cout << "number value: " << number << endl;}
private:int number;
};int main()
{int n = 100;Base* b = new (&n)Base;// >>>>> 使用placement new指定栈内存(n的)为存储空间b->print();return 0;
}

在这里插入图片描述

  • 使用定位放置new操作,既可以在栈(stack)上生成对象,也可以在堆(heap)上生成对象,这取决于定位时指定的内存地址是在堆还是在栈上。
  • 从表面上看,定位放置new操作是申请空间,其本质是利用已经申请好的空间,真正的申请空间的工作是在此之前完成的。
  • 使用定位放置new 创建对象时会自动调用对应类的构造函数,但是由于对象的空间不会自动释放,如果需要释放堆内存必须显示调用类的析构函数。
  • 使用定位放置new操作,我们可以反复动态申请到同一块堆内存,这样可以避免内存的重复创建销毁,从而提高程序的执行效率(比如网络通信中数据的接收和发送)
复杂案例
#include<iostream>
using namespace std;
class Base
{
public:void setText(string str){notes = str;}void print(){cout << "Base notes: " << notes << endl;}
private:string notes;
};union Student
{Student(){new (&name)string;//选取占内存最大的}~Student() {}int id;Base tmp;string name;
};int main()
{Student s;s.name = "蒙奇·D·路飞";cout << "Student name: " << s.name << endl;s.tmp.setText("我是要成为海贼王的男人!");s.tmp.print();cout << "Student name: " << s.name << endl;//>>>>>>共用同一块内存return 0;
}

在这里插入图片描述

匿名的非受限联合体

在这里插入图片描述

#include<iostream>
using namespace std;
/*木叶村要进行第99次人口普查,人员的登记方式如下:- 学生只需要登记所在学校的编号- 本村学生以外的人员需要登记其身份证号码- 本村外来人员需要登记户口所在地+联系方式
*/
// 外来人口信息
struct Foreigner
{Foreigner(string s, string ph) : addr(s), phone(ph) {}string addr;string phone;
};// 人口信息
class Person
{
public://枚举出人员身份enum class Category : char { Student, Local, Foreign };Person(int num) : number(num), type(Category::Student) {}Person(string id) : idNum(id), type(Category::Local) {}Person(string addr, string phone) : foreign(addr, phone), type(Category::Foreign) {}~Person() {}void print(){cout << "Person category: " << (int)type << endl;switch (type){case Category::Student:cout << "Student school number: " << number << endl;break;case Category::Local:cout << "Local people ID number: " << idNum << endl;break;case Category::Foreign:cout << "Foreigner address: " << foreign.addr<< ", phone: " << foreign.phone << endl;break;default:break;}}private:Category type;union{int number;string idNum;Foreigner foreign;};
};int main()
{Person p1(9527);Person p2("1101122022X");Person p3("砂隐村村北", "1301810001");p1.print();p2.print();p3.print();return 0;
}

在这里插入图片描述

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

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

相关文章

使用docker形式部署jumpserver

文章目录 前言一、背景二、使用步骤1.基础环境准备2.拉取镜像3.进行部署4.备份记录启动命令 前言 记录一下使用docker形式部署jumpserver服务的 一、背景 搭建一个jumpserver的堡垒机&#xff0c;但是发现之前是二进制文件部署的&#xff0c;会在物理机上部署污染环境&#x…

产品经理如何使用项目管理软件推进复杂项目按时上线

前言 相信很多产品同学或多或少都有过这样的经历&#xff1a;平时没有听到任何项目延期风险&#xff0c;但到了计划时间却迟迟无法提测……评审时没有任何argue&#xff0c;提测后发现开发的功能不是自己想要的……费劲九牛二虎之力终于让项目上线了&#xff0c;然而发现成果达…

贪心算法-汽车加油

这道题目描述了一个汽车旅行场景&#xff0c;需要设计一个有效的算法来决定在哪几个加油站停车加油&#xff0c;以便最小化加油次数。题目给出了汽车加满油后的行驶距离n公里&#xff0c;以及沿途若干个加油站的位置。我们需要找出一个方案&#xff0c;使得汽车能够完成整个旅程…

【大数据学习 | HBASE】hbase的读数据流程与hbase读取数据

1. hbase的读数据流程 在解析读取流程之前我们还需要知道两个功能性的组件和HFIle的格式信息 HFILE 存储在hdfs中的hbase文件&#xff0c;这个文件中会存在hbase中的数据以kv类型显示&#xff0c;同时还会存在hbase的元数据信息&#xff0c;包括整个hfile文件的索引大小&…

2024AAAI | DiffRAW: 利用扩散模型从手机RAW图生成单反相机质量的RGB图像

文章标题&#xff1a;《DiffRAW: Leveraging Diffusion Model to Generate DSLR-Comparable Perceptual Quality sRGB from Smartphone RAW Images》 原文链接&#xff1a;DiffRAW 本文是清华大学深圳研究院联合华为发表在AAAI-2024上的论文&#xff08;小声bb&#xff1a;华…

【Linux系统编程】第四十五弹---线程互斥:从问题到解决,深入探索互斥量的原理与实现

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、线程互斥 1.1、见一见多线程访问问题 1.2、解决多线程访问问题 1.2.1、互斥量的接口 1.2.2、互斥量接口的使用 1.2.3、…

【GVN】AWZ算法

AWZ算法的例子依旧来自于RKS的这篇文章《Detecting Equalities of Variables: Combining Efficiency with Precision》。 上面两个图&#xff0c;进行的是如下图所示的循环结构的等价类计算。 为什么得到的结果不是上图而是下图呢&#xff1f;这里其实是因为用到的AWZ的算法…

HBuilder使用虚拟机

按文档的连接一直不成功 没找到Simulator&#xff0c;原来是因为我电脑之前没安装过虚拟机版本 安装模拟器Simulator | uni-app官网 找到settings,左下角安装需要的对应版本的虚拟机就好了&#xff0c;然后重启hb

ubuntu下安装 git 及部署cosyvoice(2)

上一节已经可以了一部分。这一节&#xff0c;主要是让他动起来。 1.第一个错误 (cosyvoice) duyichengduyicheng-computer:~/gitee/CosyVoice$ python webui.py Traceback (most recent call last): File "webui.py", line 17, in <module> import grad…

16S,18S引物覆盖度测试:SILVA和PR2

16S 进入网站&#xff1a;https://www.arb-silva.de/search/testprime/ 填写引物和错配阈值 结果进入&#xff1a;Inspect Results inTaxonomy Browser 18S 进入网站&#xff1a;Primer database 进入&#xff1a;Test your primer set 可选择感兴趣的物种group&#xff0c;红…

【Kafka 实战】如何解决Kafka Topic数量过多带来的性能问题?

&#x1f449;博主介绍&#xff1a; 博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家&#xff0c;WEB架构师&#xff0c;阿里云专家博主&#xff0c;华为云云享专家&#xff0c;51CTO 专家博主 ⛪️ 个人社区&#x…

middleware中间件概述

中间件定义 中间件&#xff08;middleware&#xff09;是基础软件的一大类&#xff0c;属于可复用软件的范畴。顾名思义&#xff0c;中间件处在操作系统、网络和数据库之上&#xff0c;应用软件的下层&#xff08;如图 15-1 所示&#xff09;​&#xff0c;也有人认为它应该属…

大模型 | 2024年中国智能算力行业白皮书 | 附PDF免费下载

智能算力&#xff0c;是数字经济发展的重要基础性资源。由于美国的科技禁运政策与国内人工智能技术差距&#xff0c;我国在实现智算资源完全国产化的道路上仍需努力。为了谋求可用算力资源在物理空间的释放和高效利用&#xff0c;国家层面持续推进“东数西算”工程&#xff0c;…

面试题之---解释一下原型和原型链

实例化对象 和普调函数一样&#xff0c;只不过调用的时候要和new连用&#xff08;实例化&#xff09;&#xff0c;不然就是一个普通函数调用 function Person () {} const o1 new Person() //能得到一个空对象 const o2 Person() //什么也得不到&#xff0c;这就是普通的…

面试:TCP、UDP如何解决丢包问题

文章目录 一、TCP丢包原因、解决办法1.1 TCP为什么会丢包1.2 TCP传输协议如何解决丢包问题1.3 其他丢包情况&#xff08;拓展&#xff09;1.4 补充1.4.1 TCP端口号1.4.2 多个TCP请求的逻辑1.4.3 处理大量TCP连接请求的方法1.4.4 总结 二、UDP丢包2.1 UDP协议2.1.1 UDP简介2.1.2…

飞凌嵌入式FET527N-C核心板现已适配Android 13

飞凌嵌入式FET527N-C核心板现已成功适配Android13&#xff0c;新系统的支持能够为用户提供更优质的使用体验。那么&#xff0c;运行Android13系统的FET527N-C核心板具有哪些突出的优势呢&#xff1f; 1、性能与兼容性提升 飞凌嵌入式FET527N-C核心板搭载了全志T527系列高性能处…

Java static静态变量 C语言文件读写

1. &#xff08;1&#xff09; public class test1 {public static void main(String[] args) {javabean1.teachername"jianjun";//直接在类调用&#xff0c;方便一点点javabean1 s1 new javabean1();s1.setName("liujiawei");s1.setAge(18);s1.setGend…

Linux驱动开发(4):Linux的设备模型

在前面写的驱动中&#xff0c;我们发现编写驱动有个固定的模式只有往里面套代码就可以了&#xff0c;它们之间的大致流程可以总结如下&#xff1a; 实现入口函数xxx_init()和卸载函数xxx_exit() 申请设备号 register_chrdev_region() 初始化字符设备&#xff0c;cdev_init函数…

MYSQL隔离性原理——MVCC

表的隐藏字段 表的列包含用户自定义的列和由系统自动创建的隐藏字段。我们介绍3个隐藏字段&#xff0c;不理解也没有关系&#xff0c;理解后面的undo log就懂了&#xff1a; DB_TRX_ID &#xff1a;6 byte&#xff0c;最近修改( 修改/插入 )事务ID&#xff0c;记录创建这条记…

鸿蒙next打包流程

目录 下载团结引擎 添加开源鸿蒙打包支持 打包报错 路径问题 安装DevEcoStudio 可以在DevEcoStudio进行打包hap和app 包结构 没法直接用previewer运行 真机运行和测试需要配置签名,DevEcoStudio可以自动配置, 模拟器安装hap提示报错 安装成功,但无法打开 团结1.3版本新增工具…