(P57)面向对象版表达式计算器:单例模式与auto_ptr

news/2024/9/12 18:24:33/

文章目录

    • 1.auto_ptr在单例模式中的应用

1.auto_ptr在单例模式中的应用

  • eg:P57\01.cpp
#include <iostream>
#include <memory>
using namespace std;//单例模式是保证一个类在一个程序中只有一个对象,一个实例
//实现单例模式的关键点是:对象禁止拷贝(只需将拷贝构造函数与等号运算符声明为私有的,且并提供它的实现,这样的话,编译会报错),此外将
//构造函数声明为私有的,防止外部任意构造对象,所以需要提供一个接口ingleton::GetInstance();让外部得到这样一个对象
//因为无法通过对象调用成员函数,所以只能通过类调用成员函数,所以将GetInstance声明为static,此外,不论调用多少次GetInstance,返回的是同一个对象
//否则一个程序就有多个对象的拷贝
class Singleton
{
public://GetInstance成员函数可以访问Singleton私有的构造函数static Singleton* GetInstance(){if (instacne_ == NULL){instacne_ = new Singleton;//new:创建一个类的实例}return instacne_;}~Singleton(){cout<<"~Singleton ..."<<endl;}
private://禁止拷贝就是将拷贝构造函数,等号运算符声明为私有的,就可以保证不进行拷贝构造,也不能赋值//禁止拷贝1:禁止调用拷贝构造函数//将拷贝构造函数声明为私有的,且不提供她的实现Singleton(const Singleton& other);//禁止拷贝2://将赋值操作声明为私有的,禁止赋值操作Singleton& operator=(const Singleton& other);//将构造函数声明为私有的,在main函数中就不能调用构造函数Singleton(){cout<<"Singleton ..."<<endl;}//解决办法是使用智能指针,当智能指针生命周期结束的时候,会自动调用析构函数,从而释放指针所持有(指向)的资源//所以智能指针能用在单例模式中,对资源进行释放static Singleton* instacne_;//仅仅声明,这是裸指针,用智能指针管理// static shared_ptr<Singleton> instacne_;//当整个程序结束时,静态对象也会被销毁,就会调用这个shared_ptr类的析构函数,析构就会将其持有的指针资源进行释放
};Singleton* Singleton::instacne_;//定义性的说明int main(void)
{//Singleton s1;//Singleton s2;//不论调用几次GetInstance,总是返回同一个对象,同一个实例//如何验证他们是同一个实例?只需查看s1和s2指针所指向的地址是否一致Singleton* s1 = Singleton::GetInstance();Singleton* s2 = Singleton::GetInstance();//Singleton s3(*s1);		// 调用拷贝构造函数//s4=s2return 0;
}
  • 测试:new Singleton这个对象未被销毁,析构函数未调用。这个指针static Singleton* instacne_;未被销毁
    在这里插入图片描述

  • eg:P57\01_share_ptr.cpp

#include <iostream>
#include <memory>
using namespace std;//单例模式是保证一个类在一个程序中只有一个对象,一个实例
//实现单例模式的关键点是:对象禁止拷贝(只需将拷贝构造函数与等号运算符声明为私有的,且并提供它的实现,这样的话,编译会报错),此外将
//构造函数声明为私有的,防止外部任意构造对象,所以需要提供一个接口ingleton::GetInstance();让外部得到这样一个对象
//因为无法通过对象调用成员函数,所以只能通过类调用成员函数,所以将GetInstance声明为static,此外,不论调用多少次GetInstance,返回的是同一个对象
//否则一个程序就有多个对象的拷贝
class Singleton
{
public://GetInstance成员函数可以访问Singleton私有的构造函数static Singleton* GetInstance(){// if (instacne_ == NULL)// {// 	instacne_ = new Singleton;//new:创建一个类的实例// }// return instacne_;//get()方法返回原生指针,但没有释放所有权,release()方法会释放所有权if (!instacne_.get())){instacne_ = auto_ptr<Singleton>(new Singleton);//智能指针的所有权转移给了instacne_,instacne_持有了new Singleton所分配的内存资源}return instacne_.get();}~Singleton(){cout<<"~Singleton ..."<<endl;}
private://禁止拷贝就是将拷贝构造函数,等号运算符声明为私有的,就可以保证不进行拷贝构造,也不能赋值//禁止拷贝1:禁止调用拷贝构造函数//将拷贝构造函数声明为私有的,且不提供她的实现Singleton(const Singleton& other);//禁止拷贝2://将赋值操作声明为私有的,禁止赋值操作Singleton& operator=(const Singleton& other);//将构造函数声明为私有的,在main函数中就不能调用构造函数Singleton(){cout<<"Singleton ..."<<endl;}//解决办法是使用智能指针,当智能指针生命周期结束的时候,会自动调用析构函数,从而释放指针所持有(指向)的资源//所以智能指针能用在单例模式中,对资源进行释放// static Singleton* instacne_;//仅仅声明,这是裸指针,用智能指针管理static shared_ptr<Singleton> instacne_;//当整个程序结束时,静态对象也会被销毁,就会调用这个shared_ptr类的析构函数,析构就会将其持有的指针资源进行释放
};// Singleton* Singleton::instacne_;//定义性的说明
shared_ptr<Singleton> Singleton::instacne_;int main(void)
{//Singleton s1;//Singleton s2;//不论调用几次GetInstance,总是返回同一个对象,同一个实例//如何验证他们是同一个实例?只需查看s1和s2指针所指向的地址是否一致Singleton* s1 = Singleton::GetInstance();Singleton* s2 = Singleton::GetInstance();//Singleton s3(*s1);		// 调用拷贝构造函数//s4=s2return 0;
}
  • 测试:析构函数调用了,说明new Singleton这块资源就能够自动释放了
    在这里插入图片描述

  • eg:P57\02.cpp

#include <iostream>
#include <memory>
using namespace std;//为什么Noncopyable类是禁止拷贝的?
//(1)【采用】禁止对象拷贝的eg演示
//Noncopyable不能构造对象,因为构造对象没意义,仅仅用来继承
class Noncopyable
{
protected:Noncopyable() {};~Noncopyable() {};
private:Noncopyable(const Noncopyable&);const Noncopyable& operator=(const Noncopyable&);
};//这里继承方式是private的,why?
//这里仅仅是继承它的实现,是继承它的实现,而不是继承它的接口,所以是实现继承,而不是接口继承
class Parent : private Noncopyable
{};//Parent是禁止拷贝的,其子类Child也是禁止拷贝的,因为它也继承了Noncopyable的实现
class Child : public Parent 
{};int main(void)
{Parent p1;Parent p2(p1);//要调用Parent拷贝构造函数,Parent构造函数又调用Noncopyable的拷贝构造函数//基类的私有成员在派生类中是不能被访问的,所以编译会失败,即使能访问,基类也没//给出实现,同样也会出错Child c1;Child c2(c1);return 0;
}
  • 测试:也是禁止拷贝的
    在这里插入图片描述

  • eg:P57\03.cpp

#include <iostream>
#include <memory>
using namespace std;//为什么Noncopyable类是禁止拷贝的?
//(1)【采用】禁止对象拷贝的eg演示
//Noncopyable不能构造对象,因为构造对象没意义,仅仅用来继承
class Noncopyable
{
protected:Noncopyable() {};~Noncopyable() {};
private:Noncopyable(const Noncopyable&);const Noncopyable& operator=(const Noncopyable&);
};//这里继承方式是private的,why?
//这里仅仅是继承它的实现,是继承它的实现,而不是继承它的接口,所以是实现继承,而不是接口继承
class Parent : private Noncopyable
{
public://构造函数会调用基类的构造函数,即使没有写出Parent(): Noncopyable(),也是会自动调用的Parent()//若基类没有默认构造函数,那么在子类的成员函数列表中给出基类构造函数的调用{}//拷贝构造函数会调用基类的拷贝构造函数,但是只有Parent(const Parent& other) : Noncopyable(other)这么去写//才会调用基类的拷贝构造函数的Parent(const Parent& other) : Noncopyable(other){}
};//Parent是禁止拷贝的,其子类Child也是禁止拷贝的,因为它也继承了Noncopyable的实现
class Child : public Parent 
{};int main(void)
{Parent p1;//调用构造函数//调用拷贝构造函数,如果这么写:Parent(const Parent& other){},//Parent中实现了拷贝构造函数,是不会调用基类的拷贝构造函数,那么私有的Noncopyable(const Noncopyable&);这个限制就不生效了Parent p2(p1);//要调用Parent拷贝构造函数,Parent构造函数又调用Noncopyable的拷贝构造函数//基类的私有成员在派生类中是不能被访问的,所以编译会失败,即使能访问,基类也没//给出实现,同样也会出错// Child c1;// Child c2(c1);return 0;
}
  • 测试:
    在这里插入图片描述
  • eg:P57\04.cpp
#include <iostream>
using namespace std;//用宏来实现计算某个变量的大小
//sizeof_v
//&x+1,x变量的地址+1,也就是偏移了1个元素的地址,如果元素是4个字节就偏移4个字节
//&x+1 - &x,地址相减,实际上都是指针类型,两个指针相减得到的是他们之间的偏移量,相隔几个元素
//char*类型的地址相隔几个元素就是相隔几个字节
#define sizeof_v(x) (char*)(&x+1) - (char*)&x//使用宏来计算某个类型的大小
//sizeof_t
//((t*)0+1),t*的指针类型,偏移+1,就是偏移一个元素的t类型,得到地址的值刚好等于t类型的大小,但是得到的值类型还是一个指针
//size_t强制转换为整数
#define sizeof_t(t) (sizeof_t)((t*)0+1)//实现一个对齐的宏
//b必须是2的n次方
/*
eg:ALIGN(3, 16) 
v=3
b=16
写成二进制:
v=0011
b-1=1111,b减完1以后就是全1的
~(b-1)取反就是全0(v+b-1)就是:
v       0011
b-1     1111
=      10010(v+b-1) & ~(b-1)就是:100100000   将后面4位都抹除掉了
=   10000      
10000=16
原理思想:某个数要对齐到16的整数倍,用二进制表示的话,后面就是4个0,0000(用十进制去想,100的十进制后面有2个0)
32的整数倍,后面就是5个0
3对齐到16使用的是向上对齐,3 + 15肯定是超过16,超出的部分抹除掉,对于16而言,就是将低4位都置为0,所以得到的值就是对齐的值ALIGN(0, 16) = 0
ALIGN(16, 16) = 0
100001111
11111
*/
#define ALIGN(v, b)  ((v+b-1) & ~(b-1))//为什么要对齐宏ALIGN?因为内存池可能会使用到
/*
比如要分配3个字节,7个字节,9个字节。内存池中的内存块大小是规则的,规则的不容易产生内存碎片。(不规则的物品放在箱子里面会产生空隙或者内存碎片)
要分配内存就无法得到连续的空间,就会被浪费掉。
内存块可以是4K,16K大小的块,32K大小的块。
如果申请内存<=4K,就对齐到4K,保证申请的内存总是4K
如果是4K<内存<=16K,就对齐到16K
如果是16K<内存<=32K,就对齐到32K
采用分级的机制实现内存池
*/class Empty
{};int main(void)
{Empty e;int n;// cout << sizeof(e)<<endl;// cout<<sizeof(Empty)<<endl;//空类的大小是一个字节cout<<sizeof_v(e)<<endl;cout<<sizeof_v(n)<<endl;cout<<sizeof_t(Empty)<<endl;cout<<sizeof_t(int)<<endl;//3对齐到16的整数倍,应该是16cout<<ALLGN(3,16)<<endl;//应该是32cout<<ALLGN(31,16)<<endl;//应该是0cout<<ALLGN(0,16)<<endl;//应该是8192cout<<ALLGN(4198,4096)<<endl;return 0;
}
  • 测试:
    在这里插入图片描述

http://www.ppmy.cn/news/405672.html

相关文章

Jenkins ——pipeline入门教程

一、什么是pipeline 什么是Pipeline&#xff1f;简单来说&#xff0c;就是一套运行于Jenkins上的工作流框架&#xff0c;将原本独立运行于单个或者多个节点的任务连接起来&#xff0c;实现单个任务难以完成的复杂发布流程&#xff08;实用场景&#xff1a;将多个Jenkins构建任…

ijkplayer 支持srt协议 rtmp协议编译步骤

写在前面 ffafaf这个编译真的太垃圾了 一堆毛病 感受下webrtc 傻瓜式编译 环境首先必须ndk 是android-ndk-r15c 或者 android-ndk-r14b ubuntu 系统随便22或者20&#xff0c;18都行 有个非常重要的点python必须是2.7 不然你会看到一大堆报错 高版本的ubuntu默认都是python3…

Html中语义化的理解

语义化是指在编写HTML和CSS代码时&#xff0c;通过恰当的选择标签和属性&#xff0c;使得代码更具有语义性和可读性&#xff0c;使得页面结构和内容更加清晰明了。语义化的目的是让页面具备良好的可访问性、可维护性和可扩展性。 语义化的重要性体现在以下几个方面&#xff1a;…

Samsung ML-1640/1641/1645/2240/2241/2245/scx4200/4300/4623/4824/4828免费清零软件2.1.2完全版

有 http://download.csdn.net/source/2592047 Samsung ML-1640/1641/1645/2240/2241/2245/scx4200/4300/4623/4824/4828免费清零软件2.1.2完全版

力扣第1641

思路 当n1时&#xff1a;返回值为511111&#xff1b; 当n2时&#xff0c;返回值为1554321&#xff1b; 当n3时&#xff0c;返回值为351510631&#xff1b; 当n4时&#xff0c;返回值为7035201041&#xff1b; 即: a a e i o u e e i o u i i o u o o u u u …

代码随想录算法训练营第十五天 | 102. 二叉树的层序遍历、226. 翻转二叉树、101. 对称二叉树、每日一题 1641. 统计字典序元音字符串的数目

102. 二叉树的层序遍历 迭代法 class Solution { public:vector<vector<int>> levelOrder(TreeNode* root) {deque<TreeNode*> q;vector<vector<int>> ans;if (root) q.emplace_back(root);while (!q.empty()) {int size q.size();vector<…

【Leetcode】1641. Count Sorted Vowel Strings

题目地址&#xff1a; https://leetcode.com/problems/count-sorted-vowel-strings/ 给定一个正整数 n n n&#xff0c;问只由a, e, i, o, u组成的长 n n n的字符串中满足字典序的一共有多少个&#xff08;即不存在字典序的逆序&#xff09;。 等价于从 5 5 5个数字 1 , 2 ,…

LC-1641. 统计字典序元音字符串的数目(记忆化搜索 ==> 动态规划)

1641. 统计字典序元音字符串的数目 难度中等87 给你一个整数 n&#xff0c;请返回长度为 n 、仅由元音 (a, e, i, o, u) 组成且按 字典序排列 的字符串数量。 字符串 s 按 字典序排列 需要满足&#xff1a;对于所有有效的 i&#xff0c;s[i] 在字母表中的位置总是与 s[i1] 相…

LeetCode 1641. 统计字典序元音字符串的数目

1641. 统计字典序元音字符串的数目 给你一个整数 n&#xff0c;请返回长度为 n 、仅由元音 (a, e, i, o, u) 组成且按 字典序排列 的字符串数量。 字符串 s 按 字典序排列 需要满足&#xff1a;对于所有有效的 i&#xff0c;s[i] 在字母表中的位置总是与 s[i1] 相同或在 s[i1…

(leetcode)1641. 统计字典序元音字符串的数目

1641. 统计字典序元音字符串的数目 一、题目描述 给你一个整数 n&#xff0c;请返回长度为 n 、仅由元音 (a, e, i, o, u) 组成且按 字典序排列 的字符串数量。 字符串 s 按 字典序排列 需要满足&#xff1a;对于所有有效的 i&#xff0c;s[i] 在字母表中的位置总是与 s[i1]…

1641_strchr函数的功能分析以及peek功能实现分析

全部学习汇总&#xff1a; GreyZhang/g_unix: some basic learning about unix operating system. (github.com) 继续分析shell例程代码&#xff0c;再次遇到了一个陌生的库函数strchr。 1. 从这里看&#xff0c;这个是一个库函数无疑了。 2. 这个函数&#xff0c;或者说这三个…

【总结】1641- svelte + vite 开发 Web Components

引言 最近要做一个跨平台使用的卡片插件&#xff0c;考虑到插件的通用性&#xff0c;就选择了Web Components技术来实现 Web Components 概念 Web Components 是一套不同的技术&#xff0c;允许你创建可重用的定制元素&#xff08;它们的功能封装在你的代码之外&#xff09;并且…

力扣——1641. 统计字典序元音字符串的数目

文章目录 题目描述隔板法原理题目作答 题目描述 给你一个整数 n&#xff0c;请返回长度为 n 、仅由元音 (a, e, i, o, u) 组成且按字典序排列的字符串数量。 字符串 s 按 字典序排列 需要满足&#xff1a;对于所有有效的 i&#xff0c;s[i] 在字母表中的位置总是与 s[i1] 相同…

LeetCode 1641. 统计字典序元音字符串的数目 / 1637. 两点之间不包含任何点的最宽垂直区域 / 1053. 交换一次的先前排列

1641. 统计字典序元音字符串的数目 2023.3.29 每日一题 题目描述 给你一个整数 n&#xff0c;请返回长度为 n 、仅由元音 (a, e, i, o, u) 组成且按 字典序排列 的字符串数量。 字符串 s 按 字典序排列 需要满足&#xff1a;对于所有有效的 i&#xff0c;s[i] 在字母表中的…

【图像隐写】基于matlab分层自嵌入数字水印内容认证与恢复【含Matlab源码 1641期】

⛄一、分层自嵌入数字水印内容认证与恢复简介 为了保护图像数据的完整性、对图像进行认证和内容恢复&#xff0c;论文在分析数字水印研究现状和基本理论的基础上&#xff0c;提出一种分层自嵌入数字水印的内容认证和恢复算法。 文章的创新点在于算法在图像的变换域和空间域分层…

​力扣解法汇总1641. 统计字典序元音字符串的数目

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; https://github.com/September26/java-algorithms 原题链接&#xff1a;力扣 描述&#xff1a; 给你一个整数 n&#xff0c;请返回长度为 n 、仅由元音 (a, e, i, o, u) 组成且…

【LeetCode每日一题:1641. 统计字典序元音字符串的数目 | 从暴力递归=>记忆化搜索=>动态规划】

&#x1f34e;作者简介&#xff1a;硕风和炜&#xff0c;CSDN-Java领域新星创作者&#x1f3c6;&#xff0c;保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验分享|好用的网站工具分享&#x1f48e;&#x1f48e;&#x1f48e; &#x1f34e;座右…

[leetcode][1641]统计字典序元音字符串的数目

方法一&#xff1a;动态规划 思路与算法 状态表示&#xff1a;dp[i][j] 表示长度 i 1 的以元音字母 j 对应序号结尾的按字典序排序的字符串数量 初始状态&#xff1a;dp[0][j] 1&#xff0c;只有一个字符 状态方程&#xff1a; dp[i][j] 1, i 0 dp[i][j] Sum(j, k 0)…

【1641. 统计字典序元音字符串的数目】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 给你一个整数 n&#xff0c;请返回长度为 n 、仅由元音 (a, e, i, o, u) 组成且按 字典序排列 的字符串数量。 字符串 s 按 字典序排列 需要满足&#xff1a;对于所有有效的 i&#xff0c;s[i] 在字…

Leetcode.1641 统计字典序元音字符串的数目

题目链接 Leetcode.1641 统计字典序元音字符串的数目 Rating &#xff1a; 1519 题目描述 给你一个整数 n&#xff0c;请返回长度为 n、仅由元音 (a, e, i, o, u)组成且按 字典序排列 的字符串数量。 字符串 s按 字典序排列 需要满足&#xff1a;对于所有有效的 i&#xff0c…