C++之类作用域

目录

1、全局作用域

2、类作用域

2.1、设计模式之Pimpl

2.2、单例模式的自动释放

2.2.0、检测内存泄漏的工具valgrind

2.2.1、可以使用友元形式进行设计

2.2.2、内部类加静态数据成员形式

2.2.3、atexit方式进行

2.2.4、pthread_once形式


 

作用域可以分为类作用域、类名的作用域以及对象的作用域几部分内容。在类中定义的成员变量和成员函数的作用域是整个类,这些名称只有在类中(包含类的定义部分和类外函数实现部分)是可见的,在类外是不可见的,因此,可以在不同类中使用相同的成员名。另外,类作用域意味着不能从外部直接访问类的任何成员,即使该成员的访问权限是public,也要通过对象名来调用,对于static成员函数,要指定类名来调用。
如果发生“屏蔽”现象,类成员的可见域将小于作用域,但此时可借助this指针或“类名::”形式指明所访问的是类成员,这有些类似于使用::访问全局变量。例如:

#include <iostream>
using std::cout;
using std::endl;
int num = 1;
namespace wd
{int num = 20;class Example{public:void print(int num) const{cout << "形参num = " << num << endl;cout << "数据成员num = " << this->num << endl;cout << "数据成员num = " << Example::num << endl;cout << "命名空间中num = " << wd::num << endl;cout << "全局变量num = " << ::num << endl;}private:int num;};
}//end of namespace wdint main()
{wd::Example().print(100); //通过匿名对象调用print函数return 0;
}

和函数一样,类的定义没有生存期的概念,但类定义有作用域可见域。使用类名创建对象时,首要的前提是类名可见,类名是否可见取决于类定义的可见域,该可见域同样包含在其作用域中,类本身可被定义在3种作用域内,这也是类定义的作用域。

1、全局作用域

在函数和其他类定义的外部定义的类称为全局类,绝大多数的 C++ 类是定义在该作用域中,我们在前面定义的所有类都是在全局作用域中,全局类具有全局作用域。

2、类作用域

一个类可以定义在另一类的定义中,这是所谓嵌套类或者内部类,举例来说,如果类A定义在类B中,如果A的访问权限是public,则A的作用域可认为和B的作用域相同,不同之处在于必须使用B::A的形式访问A的类名。当然,如果A的访问权限是private,则只能在类内使用类名创建该类的对象,无法在外部创建A类的对象。

#include<iostream>
using namespace std;
class Line
{
public:Line(int x1, int y1, int x2, int y2);void printLine() const;private:class Point{public:Point(int x = 0, int y = 0): _x(x), _y(y){}void print() const;private:int _x;int _y;};
private:Point _pt1;Point _pt2;
};
Line::Line(int x1, int y1, int x2, int y2): _pt1(x1, y1), _pt2(x2, y2)
{}
void Line::printLine() const
{_pt1.print();cout << " ---> ";_pt2.print();cout << endl;
}
void Line::Point::print() const
{cout << "(" << _x<< "," << _y<< ")";
}
int main()
{Line l1(1, 2, 3, 4);l1.printLine();return 0;
}

注意:由于Point是私有类,不能在类外对其进行访问:

如果是正确定义的:

2.1、设计模式之Pimpl

PImpl是Pointer to Implementation的缩写,也被称为“编译期实现”,是一种C++设计的模式。 用于将类的实现细节与其公共接口分离开来。该模式的核心思想是 通过一个指向类的实现的指针来隐藏类的实现细节,从而提高类的封装性和安全性。

PImpl是一种C++编程技巧,它将类的实现细节从对象表示中移除,放到一个分离的类中,并以一个不透明的指针进行访问。 此技巧用于构造拥有稳定 ABI 的 C++ 库接口,及减少编译时依赖。


一.PImpl的好处
使用PImpl模式的好处是:

可以避免对实现细节的公开,从而减少了头文件中的依赖项和编译时间,并且使得类的实现可以更加灵活和方便地修改,而不会影响其公共接口。

在使用PImpl模式时,通常需要将类的实现细节封装在一个单独的结构体或类中,称为“实现类”或“pImpl类”,然后通过一个指向该实现类的指针来访问实现细节。这个指针通常作为 类的私有成员变量,并在类的构造函数和析构函数中进行初始化和清理。这样,当类的实现细节发生变化时,只需要修改实现类而不需要修改公共接口,从而实现了类的高内聚低耦合的设计目标。

 参考博客:

设计模式之Pimpl模式-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/xhtchina/article/details/112795569?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170865960916800227465939%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170865960916800227465939&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~sobaiduend~default-2-112795569-null-null.nonecase&utm_term=%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8BPimpl&spm=1018.2226.3001.4450

2.2、单例模式的自动释放

在类和对象那一章,我们看过单例模式,其中对象是由_pInstance指针来保存的,而在使用单例设计模式的过程中,也难免会遇到内存泄漏的问题。那么是否有一个方法,可以让对象自动释放,而不需要程序员自己手动去释放呢?在学习了嵌套类之后,我们就可以完美的解决这一问题。
在涉及到自动的问题时,我们很自然的可以想到:当对象被销毁时,会自动调用其析构函数。利用这一特性,我们可以解决这一问题。

2.2.0、检测内存泄漏的工具valgrind

" 安装方式:
$ sudo apt install valgrind
" 使用方式:
$ valgrind --tool=memcheck --leak-check=full ./test

2.2.1、可以使用友元形式进行设计

//1、友元实现单例对象的自动释放
class AutoRelease;
class Singleton
{friend AutoRelease;
public:static Singleton *getInstance()
{if(nullptr == _pInstance){_pInstance = new Singleton();}return _pInstance;}static void destroy(){if(_pInstance){delete _pInstance; //1、调用析构函数 2、operator delete_pInstance = nullptr;}}
private:Singleton(){cout << "Singleton()" << endl;}~Singleton(){cout << "~Singleton()" << endl;}
private:static Singleton *_pInstance;
};
Singleton *Singleton::_pInstance = nullptr;
class AutoRelease
{
public:AutoRelease(){cout << "AutoRelease()" << endl;}~AutoRelease(){cout << "~AutoRelease()" << endl;if(Singleton::_pInstance){delete Singleton::_pInstance;//1、调用析构函数 2、operator deleteSingleton::_pInstance = nullptr;}}
};

2.2.2、内部类加静态数据成员形式

class Singleton
{
public:static Singleton * getInstance(){if(_pInstance == nullptr){_pInstance = new Singleton();}return _pInstance;}private:class AutoRelease{public:AutoRelease(){cout << "AutoRelease()" << endl;}~AutoReleas(){cout << "~AutoRelease()" << endl;if(_pInstance){delete _pInstance;_pInstance = nullptr;}}};
private:Singleton(){cout << "Singleton()" << endl;}~Singleton(){cout << "~Singleton()" << endl;}private:static Singleton *_pInstance;static AutoRelease  _auto;
};

2.2.3、atexit方式进行

class Singleton
{
public:static Singleton *getInstance(){//对于多线程环境,不安全if(nullptr == _pInstance){_pInstance = new Singleton();atexit(destroy);}return _pInstance;}static void destroy(){if(_pInstance){delete _pInstance;//1、调用析构函数 2、operator delete_pInstance = nullptr;}}
private:Singleton(){cout << "Singleton()" << endl;}~Singleton(){cout << "~Singleton()" << endl;}
private:static Singleton *_pInstance;
};
/* Singleton *Singleton::_pInstance = nullptr; //饱汉模式(懒汉模式)*/
Singleton *Singleton::_pInstance = getInstance();//饿汉模式

2.2.4、pthread_once形式

//4、pthread_once,平台相关性的函数
class Singleton
{
public:static Singleton *getInstance(){pthread_once(&_once, init);return _pInstance;
}static void init(){_pInstance = new Singleton();atexit(destroy);}static void destroy(){if(_pInstance){delete _pInstance;//1、调用析构函数 2、operator delete_pInstance = nullptr;}}
private:Singleton(){cout << "Singleton()" << endl;}~Singleton(){cout << "~Singleton()" << endl;}
private:static Singleton *_pInstance;static pthread_once_t _once;
};
Singleton *Singleton::_pInstance = nullptr; //饱汉模式(懒汉模式)
/* Singleton *Singleton::_pInstance = getInstance();//饿汉模式 */
pthread_once_t Singleton::_once = PTHREAD_ONCE_INIT;

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

MobaXterm连接VirtualBox虚拟机

目录 1.下载MobaXterm 2.获取连接配置 3.mobaXterm连接虚拟机 4.更好的方案 1.下载MobaXterm 据说MobaXtrem是远程终端的超级全能神器,官网下载地址&#xff1a;MobaXterm free Xserver and tabbed SSH client for Windows 选择适合你的版本&#xff1a;一个是Home Editi…

基于编译器的静态代码分析与软件开发效率、质量和性能

基于编译器的静态代码分析与软件开发效率、质量和性能 本文节选自《基础软件之路&#xff1a;企业级实践及开源之路》一书&#xff0c;该书集结了中国几乎所有主流基础软件企业的实践案例&#xff0c;由 28 位知名专家共同编写&#xff0c;系统剖析了基础软件发展趋势、四大基…

JavaScript实现页面随着某元素自动滚动(歌词居中)

在开发过程中想要使页面随着某个元素自动滚动&#xff0c;可以使用Element.scrollIntoView()。 下面举例一个歌词的居中显示 let lyc document.querySelectorAll(.has-lyric li)[i] //获取当前播放的歌词lyc.scrollIntoView({behavior: "smooth", // 定义动画过渡…

ChatGPT/GPT4科研应用与AI绘图及论文写作

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

Flink ML 的新特性解析与应用

摘要&#xff1a;本文整理自阿里巴巴算法专家赵伟波&#xff0c;在 Flink Forward Asia 2023 AI特征工程专场的分享。本篇内容主要分为以下四部分&#xff1a; Flink ML 概况在线学习的设计与应用在线推理的设计与应用特征工程算法与应用 一、Flink ML 概况 Flink ML 是 Apache…

算法打卡day1|数组篇|Leetcode 704.二分查找、27.移除元素

数组理论基础 数组是存放在连续内存空间上的相同类型数据的集合&#xff0c;可以方便的通过下标索引的方式获取到下标下对应的数据。 1.数组下标都是从0开始的。 2.数组内存空间的地址是连续的。 正是因为数组的在内存空间的地址是连续的&#xff0c;所以我们在删除或者增添…

ShardingSphere5.x 分库分表

一、shardingSphere介绍 1、官网&#xff1a;Apache ShardingSphere 2、开发文档&#xff1a; 概览 :: ShardingSphere 3、shardingsphere-jdbc ShardingSphere-JDBC 定位为轻量级 Java 框架&#xff0c;在 Java 的 JDBC 层提供的额外服务。 它使用客户端直连数据库&#x…

转运机器人,AGV底盘小车:打造高效、精准的汽车电子生产线

为了满足日益增长的市场需求&#xff0c;保持行业领先地位&#xff0c;某汽车行业电子产品企业引入富唯智能AMR智能搬运机器人及其智能物流解决方案&#xff0c;采用自动化运输措施优化生产节拍和搬运效率&#xff0c;企业生产效率得到显著提升。 项目背景&#xff1a; 1、工厂…

【算法与数据结构】1971、LeetCode寻找图中是否存在路径

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题应用并查集的理论直接就可以解决&#xff1a;【算法与数据结构】回溯算法、贪心算法、动态规划、图…

深入浅出JVM(七)之执行引擎的解释执行与编译执行

本篇文章围绕执行引擎&#xff0c;深入浅出的解析执行引擎中解释器与编译器的解释执行和编译执行、执行引擎的执行方式、逃逸分析带来的栈上分配、锁消除、标量替换等优化以及即时编译器编译对热点代码的探测 执行引擎 hotspot执行引擎结构图 执行引擎分为解释器、JIT即时编译…

QT_day4

1.思维导图 2. 输入闹钟时间格式是小时:分钟 widget.cpp #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);id startTimer(1000);flag1;speecher new QTextT…

做抖音小店怎么选品?给新手商家的三条建议,能让你销量猛增999+

大家好&#xff0c;我是电商花花。 总是担心店铺不出单&#xff0c;没有销量&#xff0c;看着断断续续的收益&#xff0c;新手商家应该都是愁容满面吧。 今天花花从是3个维度上给新手商家一些建议&#xff0c;讲解一下如何高效选品&#xff0c;加你如何让你出单猛增999。 以前…

训练Sora模型,你可能需要这些开源代码,模型,数据集及算力评估

在之前的文章&#xff0c;我们总结了Sora模型上用到的一些核心技术和论文 复刻大模型 Sora 有多难&#xff1f;一张图带你读懂 Sora 的技术路径一文看懂大模型 Sora 技术推演 今天这篇文章来自我们社区讨论交流&#xff0c;我这边整理和总结现有的一些开源代码、模型、数据集…

【大数据】Flink 内存管理(一):设置 Flink 进程内存

Flink 内存管理&#xff08;一&#xff09;&#xff1a;设置 Flink 进程内存 1.配置 Total Memory2.JVM 参数3.根据比例限制的组件&#xff08;Capped Fractionated Components&#xff09; Apache Flink 通过严格控制各种组件的内存使用&#xff0c;在 JVM 上提供高效的工作负…

【论文阅读】ICCV 2023 计算和数据高效后门攻击

文章目录 一.论文信息二.论文内容1.摘要2.引言3.主要图表4.结论 一.论文信息 论文题目&#xff1a; Computation and Data Efficient Backdoor Attacks&#xff08;计算和数据高效后门攻击&#xff09; 论文来源&#xff1a; 2023-ICCV&#xff08;CCF-A&#xff09; 论文团…

AI文生图网站测评

主要测评文章配图生成效果、绘制logo等效果 测评关键点&#xff1a;生成效果、网站易用度、是否免费 测评prompt&#xff1a;请生成一个文章内容配图&#xff0c;图片比例是3&#xff1a;2&#xff0c;文章主旨是AI既是机遇&#xff0c;也存在挑战和风险&#xff0c;要求图片…

Matlab/simulink基于vsg的风光储调频系统建模仿真(持续更新)

​ 1.Matlab/simulink基于vsg的风光储调频系统建模仿真&#xff08;持续更新&#xff09;

leet hot 100-3 最长连续序列

两数之和 原题链接思路代码 原题链接 leet hot 100-3 128. 最长连续序列 思路 可以把所有的数字放到容器里面去 维护一个最大值 每一次去遍历数字 查看但当前数字是否为起始位置&#xff08;它的前面是否有比它小一位的数字&#xff09; 如果是起始位置 就记录一下当前值 并…

应用回归分析:泊松回归

泊松回归是一种广泛用于计数数据的回归分析方法。它适用于响应变量是非负整数的情况&#xff0c;特别是当这些计数呈现出明显的离散分布时。泊松回归通过泊松分布的概率分布函数来建模计数数据&#xff0c;使其成为处理计数数据的自然选择。本文将介绍泊松回归的基本概念、应用…

FastJson反序列化漏洞(Fastjson1.2.47)

一、FastJson Fastjson 是一个阿里巴巴公司开源的 Java 语言编写的高性能功能完善的 JSON 库。可以将Java 对象转换为 JSON 格式(序列化)&#xff0c;当然它也可以将 JSON 字符串转换为 Java 对象&#xff08;反序列化&#xff09; 它采用一种“假定有序快速匹配”的算法&…