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://www.mzph.cn/news/700833.shtml

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

相关文章

c++学习记录 STL基本概念

1、STL基本概念 STL&#xff08;Standard Template Library&#xff0c;标准模板库&#xff09;STL广义上分为&#xff1a;容器&#xff08;container&#xff09;算法&#xff08;algorithm&#xff09;迭代器&#xff08;iterator&#xff09;容器和算法之间通过迭代器进行无…

线程共享和非共享的资源及线程优缺点

注意&#xff1a;共享的内存地址空间中不包括栈&#xff1b;共享文件描述符表&#xff0c;表示&#xff0c;同一进程中线程可以操作同一文件。

猫头虎分享已解决Bug || TypeError: Cannot read property ‘props‘ of undefined (React)

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

c++的类型转换方法

一、静态类型转换&#xff08;static_cast&#xff09; 静态类型的转换主要用于基本类型之间的转换&#xff0c;比如int类型转换为double类型。但是static_cast也可以支持上下行的转换&#xff08;存在继承关系之间的转换&#xff09; 基本类型之间的转换举例 上下行转换的举…

金航标电子位于广西柳州鹿寨县天线生产基地于大年正月初九开工了!!!

金航标kinghelm&#xff08;www.kinghelm.com.cn&#xff09;总部位于中国深圳市&#xff0c;兼顾技术、成本、管理、效率和可持续发展。东莞塘厦实验室全电波暗室、网络分析仪、高低温测试柜等仪器设备齐全&#xff0c;可进行高低温、双85等测试&#xff0c;独立完成产品的检测…

数字化转型导师坚鹏:数据安全法解读与政府数字化转型

网络安全法、数据安全法、个人信息保护法解读与政府数字化转型 课程背景&#xff1a; 很多机构存在以下问题&#xff1a; 不清楚网络安全法、数据安全法、个人信息保护法立法背景&#xff1f; 不知道如何理解网络安全法、数据安全法、个人信息保护法政策&#xff1f; 不…

高级RAG:使用RAGAs + LlamaIndex进行RAG评估,包括原理、图和代码

原文地址&#xff1a;Using RAGAs LlamaIndex for RAG evaluation 2024 年 2 月 5 日 如果您已经为实际的业务系统开发了检索增强生成&#xff08;Retrieval Augmented Generation, RAG&#xff09;应用程序&#xff0c;那么您可能会关心它的有效性。换句话说&#xff0c;您…

Golin 弱口令/漏洞/扫描/等保/基线核查的快速安全检查小工具

下载地址&#xff1a; 链接&#xff1a;https://pan.quark.cn/s/db6afba6de1f 主要功能 主机存活探测、漏洞扫描、子域名扫描、端口扫描、各类服务数据库爆破、poc扫描、xss扫描、webtitle探测、web指纹识别、web敏感信息泄露、web目录浏览、web文件下载、等保安全风险问题风险…

【前端素材】推荐优质后台管理系统Start Admin平台模板(附源码)

一、需求分析 后台管理系统是一种用于管理网站、应用程序或系统的工具&#xff0c;它通常作为一个独立的后台界面存在&#xff0c;供管理员或特定用户使用。下面详细分析后台管理系统的定义和功能&#xff1a; 1. 定义 后台管理系统是一个用于管理和控制网站、应用程序或系统…

nios ii开发随笔

错误一&#xff1a; d:/intelfpga/17.1/nios2eds/bin/gnu/h-x86_64-mingw32/bin/../lib/gcc/nios2-elf/5.3.0/../../../../../H-x86_64-mingw32/nios2-elf/bin/ld.exe: test.elf section .text will not fit in region ram_oc_xzs d:/intelfpga/17.1/nios2eds/bin/gnu/h-x86_6…

鸿蒙OS应用开发之显示图片组件6

前面学习了怎么样让图片合适的大小来显示出来,达到最佳的布局显示图片。现在来学习PixelMap图片显示。PixelMap图片是指图片解码后无压缩的位图,用于图片显示或图片处理。 由于PixelMap图片是一种无压缩的图片,比较适合图片处理,比如从网络上加载图片之后,再进行处理再显示…

STM32-启用蜂鸣器

目录 1 、电路构成及原理图 2、编写实现代码 main.c beep.c beep.h 3、代码讲解 4、 烧录到开发板调试、验证代码 5、检验效果 本人使用的是朗峰 STM32F103 系列开发板&#xff0c;此笔记基于这款开发板记录。 1 、电路构成及原理图 首先&#xff0c;通过朗峰 F1 开…

SpringBoot 3 新特性

目录 1. GraalVM2. 支持虚拟线程3. HTTP Interface 1. GraalVM 使用GraalVM将SpringBoot应用程序编译成本地可执行的镜像文件&#xff0c;可以显著提升启动速度、峰值性能以及减少内存应用。传统的应用都是编译成字节码&#xff0c;然后通过JVM解释并最终编译成机器码来运行&a…

ELK入门(二)- springboot整合ES

springboot整合elasticsearch 引用依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http…

TT语音×个推:流失预测准确率超90%,撬动存量增长个推GeTui 2024-02-23 09:50 浙江

当移动互联网进入存量时代&#xff0c;如何更高效地进行用户全生命周期管理、提升用户生命周期价值&#xff0c;变得尤为重要。TT语音是国内领先的兴趣社交平台&#xff0c;累计注册用户数高达数亿。为了进一步盘活存量用户价值&#xff0c;TT语音从2019年起便与个推合作&#…

三分钟快速搭建家纺行业小程序商城:轻松实现电子商务梦想

随着互联网的普及和移动设备的广泛使用&#xff0c;越来越多的商业活动正在向数字化转型。在这个过程中&#xff0c;小程序商城作为一种新型的电子商务模式&#xff0c;正逐渐受到商家的青睐。本文将通过具体步骤&#xff0c;指导读者如何开发一个纺织辅料小程序商城。 一、选择…

EarMaster Pro 7 简体中文破解版下载 v7.2.0.42 电脑版

软件介绍 EarMaster Pro 简体中文破解版是一款由丹麦皇家音乐学院官方制作的多功能音乐品鉴教育软件&#xff0c;软件具有丰富的功能&#xff0c;它可以自定义培训课程&#xff0c;针对性地训练音准、节奏、和声等音乐要素&#xff0c;用户可以根据自身需求和水平选择不同难度…

【探索Linux】—— 强大的命令行工具 P.23(线程池 —— 简单模拟)

阅读导航 引言一、线程池简单介绍二、Linux下线程池代码⭕Makefile文件⭕ . h 头文件✅Task.hpp✅thread.hpp✅threadPool.hpp ⭕ . cpp 文件✅testMain.cpp 三、线程池的优点温馨提示 引言 在Linux下&#xff0c;线程池是一种常见的并发编程模型&#xff0c;它能够有效地管理…

一键搭建Tex书写环境【免费、开源】

安装 # 安装 vscode scoop install extras/vscode # 安装 cmder(windows下超好用的命令行工具&#xff0c;可选) scoop install main/cmder-full # 安装 miktex scoop install main/miktex配置 将我的VSCode配置文件导入到 VSCode 即可。 VSCode for Latex 配置文件 具体步…

neo4j创建新数据库

根据网上提供的教程&#xff0c;neo4j并没有提供创建数据库的命令&#xff0c;其只有一个默认数据库graph.db&#xff0c;该数据库中的所有数据将存储在neo4j安装路径下的data/databases/graph.db目录中。 因此&#xff0c;我们猜想&#xff0c;如果我们将默认数据库的名字修改…