C++特殊类的设计与类型转换
特殊类的设计与类型转换
- 特殊类的设计
- 请设计一个类,只能在堆上创建对象
- 请设计一个类,只能在栈上创建对象
- 请设计一个类,只能创建一个对象(单例模式)
- C++的类型转换
特殊类的设计
请设计一个类,只能在堆上创建对象
通过new创建的类就是堆上的。
方法一:
#include<iostream>using namespace std;
class HeapOnly
{
public:static HeapOnly* func()//这里如果不用静态就无法创建对象了,也导致这个函数无法被调用{return new HeapOnly;}
private:HeapOnly()//防止随意的创建对象{}HeapOnly(const HeapOnly& a) = delete;//如果不删除拷贝函数创建的对象还是在栈上
};
int main()
{HeapOnly* p1 = HeapOnly::func();//HeapOnly p2(*p1);//这样避免了p2对象创建在栈上return 0;
}
这里主要以封禁构造函数为主,让外部只能通过调用func函数方式去创建对象,func函数的内部是通过new创建的,这里要注意的就是拷贝构造的问题。
赋值重载不用删除,因为需要现有一个对象才能赋值给另一个对象,上面的代码只会创建出堆上的对象。
方法二:
#include<iostream>using namespace std;class HeapOnly
{
public:HeapOnly(){}void Delete(){this->~HeapOnly();}
private:~HeapOnly(){}HeapOnly(const HeapOnly& a) = delete;
};int main()
{HeapOnly* p1 = new HeapOnly;p1->Delete();return 0;
}
封禁析构函数,需要自己手动释放内存。
请设计一个类,只能在栈上创建对象
这里要注意一点,静态区也不行。
方法一:
#include <iostream>
using namespace std;
class NonInherit
{
public:static NonInherit func(){return NonInherit();}void Pintf(){cout << "Pintf" << endl;}
private:NonInherit(){}NonInherit(const NonInherit& p) = delete;
};
int main()
{NonInherit::func().Pintf();//static NonInherit p1 = NonInherit::func();//防止p1创建在静态区上return 0;
}
这里就像匿名对象的感觉,如果不封拷贝构造就会出现注释上的问题。
方法二:
#include <iostream>
using namespace std;
class NonInherit
{
public:static NonInherit func(){return NonInherit();}void Pintf() const{cout << "Pintf" << endl;}
private:NonInherit(){}NonInherit(const NonInherit& p) = delete;
};
int main()
{const NonInherit& p1 = NonInherit::func();//用引用接收p1.Pintf();//然后在使用return 0;
}
请设计一个类,只能创建一个对象(单例模式)
设计模式:
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。
单例模式:
一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。
单例模式有两种实现模式:
饿汉模式
就是说不管你将来用不用,程序启动时就创建一个唯一的实例对象。
#include<iostream>
#include<map>
#include<string>
using namespace std;
class Singleton
{
public:static Singleton& func(){return _a;//拿到对象本身}void Insert(string str, int salary){arr[str] = salary;}void Printf(){for (auto& e : arr){cout << e.first << ":" << e.second << endl;}}
private:Singleton(){}Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;map<string, int> arr;static Singleton _a;
};
Singleton Singleton::_a;//在外部初始化对象,同类对象只会调用一次构造函数int main()
{Singleton::func().Insert("aaa", 111);Singleton&p = Singleton::func();p.Insert("bbb", 222);p.Insert("ccc", 333);p.Insert("ddd", 444);p.Insert("eee", 555);p.Printf();return 0;
}
这个模式缺点:
如果数据量太大,启动就会非常的缓慢。
如果有多个文件一起,都有饿汉模式的代码,他们互相之间有依赖,但是编译器很难控制先初始化谁。
懒汉模式
如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊, 初始化网络连接啊,读取文件啊等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化,就会导致程序启动时非常的缓慢。 所以这种情况使用懒汉模式(延迟加载)更好。
#include<iostream>
#include<map>
#include<string>
#include<mutex>
using namespace std;
template<class T>
class Lock
{
public:Lock(T& p)//因为锁不允许拷贝:_p(p){_p.lock();}~Lock(){_p.unlock();}
private:T& _p;//所以这里成员用引用
};
class Singleton
{
public:static Singleton& func(){if (_a == nullptr)//避免每次调用的时候都进行加锁的操作,提高效率{Lock<mutex> p(mex);//用智能指针是为了防止下面的new出现异常导致未解锁//如果不加锁,容易发生内存泄露,开辟多个空间,最终指针只会指向一处空间if (_a == nullptr)//第一次调用创建对象{_a = new Singleton;}}return *_a;}void Insert(string str, int salary){arr[str] = salary;}void Printf(){for (auto& e : arr){cout << e.first << ":" << e.second << endl;}}
private:Singleton(){}Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;map<string, int> arr;static Singleton* _a;static mutex mex;//锁
};
Singleton* Singleton::_a = nullptr;//在外部初始化对象,同类对象只会调用一次构造函数
mutex Singleton::mex;//定义锁
int main()
{Singleton::func().Insert("aaa", 111);Singleton& p = Singleton::func();p.Insert("bbb", 222);p.Insert("ccc", 333);p.Insert("ddd", 444);p.Insert("eee", 555);p.Printf();return 0;
}
并且,一般单例对象不用考虑释放,因为一个进程在结束的时候资源会回收给OS。
如果有需要处理的资源,需要在内部定义一个函数去处理某个资源,然后其他资源不用处理:
static void Delete()//手动释放资源
{Lock<mutex> p(mex);if (_a != nullptr){delete _a;_a = nullptr;}
}
假如忘记回收这个资源了呢?
在内部定义一个GC的类,这个类的析构函数内部调用上面的Delete函数。
class GC
{
public:~GC(){if (_a){cout << "~GC()" << endl;Delete();}}
};
然后再外部定义一个全局的GC类的对象,在程序结束的时候就会去调用析构函数。
主要是帮助检查有没有手动释放掉这一出资源。
注意:C++11前是无法保证线程静态的初始化是安全的,C++11之后可以。
也就是说懒汉还有这种写法:
static Singleton& func()
{static Singleton _a;return _a;
}
函数的成员也就不用了静态对象。
C++的类型转换
C语言有两种类型转换,一个是隐式类型转换,另一个是强制类型转换。
#include<iostream>
using namespace std;int main()
{//隐式类型int a = 1;double b = a;//强制类型int c = 10;int* p = &c;int d = (int)p;return 0;
}
C++有四种类型转换,是期望大家能够规范使用的。
为什么C++需要四种类型转换
C风格的转换格式很简单,但是有不少缺点的:
1.隐式类型转化有些情况下可能会出问题:比如数据精度丢失。
2.显式类型转换将所有情况混合在一起,代码不够清晰。
因此C++提出了自己的类型转化风格,注意因为C++要兼容C语言,所以C++中还可以使用C语言的转化风格。
static_cast
static_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用。
static_cast,但它不能用于两个不相关的类型进行转换。
reinterpret_cast
reinterpret_cast操作符通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换
为另一种不同的类型。
const_cast
const_cast最常用的用途就是删除变量的const属性,方便赋值。
这里看起来并没有被赋值成功是因为编译器进行了优化,认为const的变量不会被修改,所以这个值一直放在了寄存器中,并没有从内存中获取,数据一直未被更新到寄存器当中。
dynamic_cast
dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换)
向上转型:子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则)
向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是安全的)
注意:
1.dynamic_cast只能用于父类含有虚函数的类
2. dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0
#include<iostream>
using namespace std;
class A
{
public:virtual void f() {}int a;
};
class B : public A
{
public:int b;
};
void fun(A* pa)
{// dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回B* pb = dynamic_cast<B*>(pa);//子类指向父类,访问父类的内容的时候虚表可能会越界产生报错if (pb)//检查是否合法,其实就是拒绝了子类指向父类{pb->a++;pb->b++;cout << "a++ " << "b++" << endl;}
}
int main()
{A a;B b;fun(&a);fun(&b);return 0;
}
注意:
强制类型转换关闭或挂起了正常的类型检查,每次使用强制类型转换前,程序员应该仔细考虑是
否还有其他不同的方法达到同一目的,如果非强制类型转换不可,则应限制强制转换值的作用
域,以减少发生错误的机会。强烈建议:避免使用强制类型转换。
相关文章:

C++特殊类的设计与类型转换
特殊类的设计与类型转换 特殊类的设计请设计一个类,只能在堆上创建对象请设计一个类,只能在栈上创建对象请设计一个类,只能创建一个对象(单例模式) C的类型转换 特殊类的设计 请设计一个类,只能在堆上创建对象 通过new创建的类就…...
如何通过关键词搜索API接口
如果你是一位电商运营者或者是想要进行1688平台产品调研的人员,你可能需要借助API接口来获取你所需要的信息。在这篇文章中,我们将会讨论如何通过关键词搜索API接口获取1688的商品详情。 第一步:获取API接口的授权信息 在使用API接口前&…...
智驾域控新战争打响,谁在抢跑?
智能驾驶域控制器赛道,已经成为了时下最为火热的市场焦点之一。 最近,头部Tier1均胜电子公布了全球首批基于高通Snapdragon Ride第二代芯片平台的智能驾驶域控制器产品nDriveH,在这一赛道中显得格外引人注意。 就在不久之前,均胜…...
Android 13无源码应用去掉无资源ID的按钮
Android Wifionly项目,客户要求去掉谷歌联系人里的 手机联系人按钮 需求分析 无应用源码,只能通过系统侧去修改 首先通过 Android Studio 工具 uiautomatorviewer 获取父控件资源ID chip_group ,然后通过遍历获取子控件去掉目标按钮 --- a/frameworks/base/core/java/andr…...
【SCI征稿】中科院2区(TOP),正刊,SCIEEI双检,进化计算、模糊集和人工神经网络在数据不平衡中应用
【期刊简介】IF:8.0-9.0,JCR1区,中科院2区(TOP) 【检索情况】SCIE&EI 双检,正刊 【数据库收录年份】2004年 【国人占比】22.78%(期刊国际化程度高) 【征稿领域】进化计算、模…...
Android Audio开发——AAudio基础(十五)
AAudio 是一个自 Android O 引入的新的 Android C API。它主要是为需要低延迟的高性能音频应用设计的。应用程序通过直接从流中读取或向流中写入数据来与 AAudio 通信,但它只包含基本的音频输入输出能力。 一、AAudio概述 AAudio 在应用程序和 Android 设备上的音频输入输出之…...

SDK接口远程调试【内网穿透】
文章目录 1.测试环境2.本地配置3. 内网穿透3.1 下载安装cpolar内网穿透3.2 创建隧道 4. 测试公网访问5. 配置固定二级子域名5.1 保留一个二级子域名5.2 配置二级子域名 6. 使用固定二级子域名进行访问 转发自cpolar内网穿透的文章:Java支付宝沙箱环境支付࿰…...

Mybatis学习笔记二
目录 一、MyBatis的各种查询功能1.1 查询一个实体类对象1.2 查询一个List集合1.3 查询单个数据1.4 查询一条数据为map集合1.5 查询多条数据为map集合1.5.1 方法一:1.5.2 方法二: 二、特殊SQL的执行2.1 模糊查询2.2 批量删除2.3 动态设置表名2.4 添加功能…...

大屏数据可视化开源项目
一、DataGear —— 数据可视化项目 官网:DataGear - 开源免费的数据可视化分析平台 DataGear 是一款开源免费的数据可视化分析平台,数据可视化看板。 功能特性: 1、多种数据源,支持运行时接入任意提供 JDBC 驱动的数据库&#…...
面试经典150题:数组/字符串合集
新专栏,预计两个月写完吧,每天下班回来抽空做几道题。会把做题计划顺序记录下来,如果你有缘,刷到这个开篇序列,那就跟着文章去练题吧。初学者可以慢慢来 88. 合并两个有序数组 void merge(vector<int>& nums…...
Java源文件的执行过程
目录 1.JVM 2.字节码 3.Java源文件执行的过程 4.JIT(Just In Time Compilation) 5.AOT(Ahead Of Time Compilation) 6.AOT破坏Java动态性 7.编译型语言与解释型语言 8.Java-编译与解释并存的语言 9.Java和C的相同点与不同…...

10个ai算法常用库java版
今年ChatGPT 火了半年多,热度丝毫没有降下来。深度学习和 NLP 也重新回到了大家的视线中。有一些小伙伴问我,作为一名 Java 开发人员,如何入门人工智能,是时候拿出压箱底的私藏的学习AI的 Java 库来介绍给大家。 这些库和框架为机器学习、深度学习、自然语言处理等提供了广…...
怎么看服务器带宽大小 103.219.179.X
第一种,可以使用网站测速,这种方式比较便捷,但是由于网站测速是测试服务器发送数据包到他网站节点的一个速度情况,有时候节点问题或者服务器做了封包限制可能导致测试不准确的情况。 第二种,可以在IIS上架设一个大一点…...

图形编辑器开发:最基础但却复杂的选择工具
大家好,我是前端西瓜哥。 对于一个图形设计软件,它最基础的工具是什么?选择工具。 但这个选择工具,却是相当的复杂。这次我来和各位,细说细说选择工具的一些弯弯道道。 我正在开发的图形设计工具的: http…...
apk签名-signapk.jar
如果做平台app开发,需要签platform签名,除了通过adroid.bp或者android.mk的方式使用AOSP整个大工程中签名外,还可以直接通过signapk.jar的方式进行签名,效率更高更快捷简便。 首先我们来回顾下AOSP平台签名的办法。 Android.mk 使…...

【100个高大尚求职简历】简历模板+修改教程+行业分类简历模板 (涵盖各种行业) (简历模板+编辑指导+修改教程)
文章目录 1 简历预览2 简历下载 很多人说自己明明投了很多公司的简历,但是都没有得到面试邀请的机会。自己工作履历挺好的,但是为什么投自己感兴趣公司的简历,都没有面试邀请的机会。反而是那些自己没有投递的公司,经常给自己打电…...
Nginx平滑升级版本或添加模块
文章目录 一、Nginx 平滑升级二、升级失败 回滚操作三、遇到问题 一、Nginx 平滑升级 一般有两种情况下需要升级 nginx,一种是确实要升级 nginx 的版本,另一种是要为 nginx 添加新的模块。 Nginx平滑升级其原理简单概括: (1&am…...

高阶复杂网络重建:从时间序列中重建高阶网络
论文链接:https://www.nature.com/articles/s41467-022-30706-9 一、为什么要研究高阶网络? 复杂网络跟我们生活息息相关,例如社交网络的信息传播,疾病的感染扩散和基因调控网络的相互作用等。越来越多的研究突破了传统网络中两…...

Day05 03-MySQL主从-主主原理与搭建详解
文章目录 第十六章 MySQL的系统架构(主从架构)16.1 MySQL集群架构的介绍16.1.1 主从架构介绍16.1.2 主从复制的原理 16.2 MySQL主从复制的实现16.2.1 环境说明16.2.2 主库配置16.2.3 从库配置16.2.4 主从复制测试 16.3 MySQL主主复制的实现16.3.1 主主复…...

STL之vector
目录 vector模拟实现一. vector的基本框架二. 常用方法及实现1.初始化和清理a. 默认构造函数b. 析构函数 2. 迭代器a. beginb. end 3.数据访问a. sizeb. capacityc. operator[]d. frontc. back 4.增删查改操作a. reserveb. resizec. insertd. push_backe. erasef. pop_back 5.构…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...

【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...

python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...

对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...