C++之类作用域

news2024/10/7 14:32:27

目录

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 wd

int 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 delete
      Singleton::_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.coloradmin.cn/o/1467092.html

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

相关文章

【MIT-PHP-推荐】imi-ai 是一个 ChatGPT 开源项目

mi-ai 是一个 ChatGPT 开源项目&#xff0c;支持聊天、问答、写代码、写文章、做作业等功能。 项目架构合理&#xff0c;代码编写优雅&#xff0c;简单快速部署。前后端代码完全开源&#xff0c;不管是学习自用还是商用二开都很适合。 本项目现已支持 ChatGPT 聊天 AI 和 Emb…

PyTorch概述(五)---LINEAR

torch.nn.Linear torch.nn.Linear(in_features,out_features,biasTrue,deviceNone,dtypeNone) 对输入的数据应用一个线性变换&#xff1a; 该模块支持TensorFLoat32类型的数据&#xff1b;在某些ROCm设备上&#xff0c;使用float16类型的数据输入时&#xff0c;该模块在反向传…

电路设计(28)——交通灯控制器的multisim仿真

1.功能设定 南北、东西两道的红灯时间、绿灯时间均为24S&#xff0c;数码管显示倒计时。在绿灯的最后5S内&#xff0c;黄灯闪烁。有夜间模式&#xff1a;按下按键进入夜间模式。在夜间模式下&#xff0c;数码管显示计数最大值&#xff0c;两个方向的黄灯不停闪烁。 2.电路设计 …

高通XBL阶段读取分区

【需求】: 在某些场景下,需要在XBL阶段读取分区数据,需要验证xbl阶段方案 这里主要以裸分区为例,比如oem分区。 1、创建一个1MB大小的oem.img,写入内容“test oem partition” 创建方式: dd if=/dev/null of=oem.img bs=1024 count=1oem.img内容: 2、XBL阶段读分区方…

一个更好的IP工具箱MyIP

什么是 MyIP &#xff1f; MyIP 是一个完全开源的 IP 信息查看器&#xff0c;可以轻松检查你的 IP&#xff0c;IP 地理位置&#xff0c;检查 DNS 泄漏&#xff0c;检查 WebRTC 连接&#xff0c;速度测试&#xff0c;ping 测试&#xff0c;MTR 测试&#xff0c;检查网站可用性等…

洛谷C++简单题小练习day20—小狗暴躁,津津的不高兴程度两个小程序(祝大家元宵节happy)

day20--小狗暴躁--2.24 习题概述 题目描述 在一个小村子里&#xff0c;邮递员、送奶工、垃圾清理工每天早晨都面临着同样的难题&#xff1a;18 号房子的门前有两条看门狗。他们所不知道的是&#xff0c;这两条狗的表现是有迹可循的。 当一天开始时&#xff0c;其中一条狗会…

流畅的Python笔记

流畅的Python 第一部分 序幕第 1 章 Python 数据模型 第二部分 数据结构第 2 章 序列构成的数组列表推导生成器表达式元组切片对序列使用和*序列的增量赋值list.sort方法和内置函数sortedbisect数组memoryviewdeque 第 3 章 字典和集合第 4 章 文本和字节序列 第三部分 把函数视…

Leetcode 209.长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;返回 0 。 示例 1&#xff1a; 输入&…

Linux---权限管理(ACL权限、特殊位和隐藏属性)

目录 1.ACT权限 1.1什么是ACT权限 1.2ACT图解 2.操作步骤 2.1添加测试目录、用户、组&#xff0c;并将用户添加到组 2.2修改目录的所有者和所属组 2.3设定权限 2.4为临时用户分配权限 2.4.1添加临时用户 2.4.2为临时用户分配特定权限 2.4.3查看目录权限&#xff0c;注…

Moment.js——轻松处理日期和和时间,有实例代码

hello&#xff0c;我是贝格前端工场&#xff0c;本期给大家带来便捷的处理日期和时间的js库&#xff1a;Moment.js&#xff0c;用这个类库处理时间将会十分方便&#xff0c;欢迎老铁们点赞关注&#xff0c;如有前端定制开发需求可以私信我们。 一、Moment.js的简介和功能 Mom…

C++多线程同步(上)

多线程同步 引言总述详情互斥锁示例运行结果分析条件变量示例一实现分析优化运行结果示例二实现代码运行结果示例三实现代码运行结果读写锁示例实现代码注意分析运行结果附言实现运行结果运行结果个人心得引言 项目中使用多线程,会遇到两种问题,一种是对共享资源的访问时需要…

echarts多y轴样式重叠问题

1、主要属性设置 yAxis: [{//y轴1nameTextStyle: {align: "right",padding: 0}},{//y轴2nameTextStyle: {align: "left",padding: 0}},{//y轴3axisLabel: {margin: 50},nameTextStyle: {align: "left",padding: [0, 0, 0, 50]},axisPointer: {l…

Web基础02 -CSS+CSS3

目录 一、CSS 1.CSS盒模型 2.元素宽度计算 3.元素高度计算 4.宽度和高度的度量单位 5.设置元素的极限宽高 6.CSS属性&#xff08;第二部分&#xff09; &#xff08;1&#xff09;纯色背景 &#xff08;2&#xff09;图片背景 &#xff08;3&#xff09;列表样式 &am…

Tomcat信创平替之TongWEB(东方通),安装步骤

我的系统: 银河麒麟桌面系统V10(SP1) 开局先吐槽一下(当然国产也是需要大量时间与金钱的投入),感觉国产软件进入死循环:国家推动国产→国产收费→还要钱?→用国外开源→国产无发普及→靠国家推动 正题: 1.先进入东方通申请使用 2.客服会发送一个TongWEB包与license.dat给你…

leet hot 100-1 两数之和

两数之和 原题链接思路代码 原题链接 leet hot 100-1 1. 两数之和 思路 可以把当前数字放到容器里面去 当我们遍历一个新的数字的时候 减一下与目标值的差 然后得到的结果在容器里面查看是否存在 时间复杂度O(n) 空间复杂度(n) 代码 class Solution { public:vector<…

【漏洞复现】大华DSS视频管理系统信息泄露漏洞

Nx01 产品简介 大华DSS数字监控系统是一个在通用安防视频监控系统基础上设计开发的系统&#xff0c;除了具有普通安防视频监控系统的实时监视、云台操作、录像回放、报警处理、设备治理等功能外&#xff0c;更注重用户使用的便利性。 Nx02 漏洞描述 大华DSS视频管理系统存在信…

Redis能保证数据不丢失吗?

引言 大家即使没用过Redis&#xff0c;也应该都听说过Redis的威名。 Redis是一种Nosql类型的数据存储&#xff0c;全称Remote Dictionary Server&#xff0c;也就是远程字典服务器&#xff0c;用过Dictionary的应该都知道它是一种键值对&#xff08;Key-Value&#xff09;的数…

Spring中的ApplicationContext.publishEvent

简单理解 其实就是监听处理。比如找工作平台上&#xff0c;雇主 employer 发布自己的雇佣条件&#xff0c;目的是平台中有符合条件的求职者时&#xff0c;及时向雇主推荐。求职者发布简历&#xff0c;当平台发现某个求职者比较符合条件&#xff0c;就触发被动&#xff0c;推荐…

【刷题记录】链表的回文结构

本系列博客为个人刷题思路分享&#xff0c;有需要借鉴即可。 1.题目链接&#xff1a; LINK 2.详解思路&#xff1a; 思路&#xff1a;思路&#xff1a;先找到中间节点&#xff0c;然后逆置后半部分链表&#xff0c;一个指针指向链表的头节点&#xff0c;再一个指针指向逆置的头…

Stable Diffusion 3 发布,AI生图效果,再次到达全新里程碑!

AI生图效果&#xff0c;再次到达全新里程碑&#xff01; Prompt&#xff1a;Epic anime artwork of a wizard atop a mountain at night casting a cosmic spell into the dark sky that says "Stable Diffusion 3" made out of colorful energy 提示&#xff08;意译…