C++之对象的使用

news2025/1/10 22:54:01

1、static成员

2、static成员优点

2、static成员函数

静态成员函数不能访问非静态成员原因:因为没有this指针。也不可以访问非静态成员函数。

可以通过对象来访问静态成员,但是不推荐这么使用,会让人误解成这个x_是属于对象的,但是静态成员是属于类的。

3、类/对象大小计算

一个虚函数,会增加4个字节,因为增加了一个虚函数表指针。

4、四种对象的作用域与生存期

bss区,即block started by symbol,因为未初始化的数据,在可执行文件中不占用空间,因为他们的初始值都为0,既然等于0,我们只需要一个符号来表示即可,不需要再为它们分配空间。

5、static用法总结

6、static与单例模式

禁止拷贝:将拷贝构造函数和等号运算符声明为私有的,这样就不允许拷贝和赋值

#include <iostream>
using namespace std
class Singleton
{
public:
    static Singleton* GetInstance()
    {
        if(instacne_== NULL)
        {
            instacne_= new Singleton;
        }
        return instacne_
    }
    
    ~Singleton()
    {
        cout<<"Singleton"<<endl;
    }
private:
    Singleton(const Singleton& other);
    Singleton& operator=(const Singleton& other)
    Singleton()
    {
        cout << "Singleton..." << endl;
    }

    static Singleton* instacne_;
}

Singleton* Singleton::instacne_;

int main(void)
{
    //Singleton sl;
    //Singleton s2;

    Singleton* sl = Singleton::GetInstance();
    Singleton* s2 = Singleton::GetInstance();

    //Singleton s3(*s1)  // 调用拷贝构造函数

    return 0;
}

还有就是:在构造函数中,开辟的内存,在单例的这个对象生命周期结束的时候自动释放

方法一:提供一个释放内存的方法,主动调用

#include <iostream>
using namespace std
class Singleton
{
public:
    static Singleton* GetInstance()
    {
        if(instacne_== NULL)
        {
            instacne_= new Singleton;
        }
        return instacne_
    }
    
    ~Singleton()
    {
        cout<<"Singleton..."<<endl;
    }

    static void Free()
    {
        if (instance_ != NULL)
        {
            delete instance_;
        }
    }
private:
    Singleton(const Singleton& other);
    Singleton& operator=(const Singleton& other)
    Singleton()
    {
        cout << "Singleton..." << endl;
    }

    static Singleton* instacne_;
}

Singleton* Singleton::instacne_;

int main(void)
{
    //Singleton sl;
    //Singleton s2;

    Singleton* sl = Singleton::GetInstance();
    Singleton* s2 = Singleton::GetInstance();

    //Singleton s3(*s1)  // 调用拷贝构造函数

    Singleton::Free()
    return 0;
}

但是这样缺点也很明显:如果一个程序很多地方都使用了一个单例的对象,我们要释放,要在哪里释放?这个就不好控制了。我们需要的是在这个对象的声明周期结束的时候自动释放。

方法二:提供一个内嵌的嵌套类,然后再定义一个嵌套类的对象,当该单例对象的声明周期结束的时候,这个嵌套类的对象也就释放了。

#include <iostream>
using namespace std
class Singleton
{
public:
    static Singleton* GetInstance()
    {
        if(instance_== NULL)
        {
            instance_= new Singleton;
        }
        return instance_
    }
    
    ~Singleton()
    {
        cout<<”Singleton'<<endl;
    }

    //static void Free()
    //{
    //    if (instance_ != NULL)
    //    {
    //        delete instance_;
    //    }
    //}
    
    class Garbo
    {
    public:
        ~Garbo()
        {
            if(Singleton::instance_!= NULL)
            {
                delete instance_,
            }
        }
    }

private:
    Singleton(const Singleton& other);
    Singleton& operator=(const Singleton& other)
    Singleton()
    {
        cout << "Singleton..." << endl;
    }

    static Singleton* instance_;

    static Garbo garbo_;  // 利用对象的确定性析构:因为是在栈上的内存,生命周期结束的时候会自动调用~Garbo()这个析构函数
}

Singleton* Singleton::instance_;
Singleton::Garbo Singleton::garbo_;

int main(void)
{
    //Singleton sl;
    //Singleton s2;

    Singleton* sl = Singleton::GetInstance();
    Singleton* s2 = Singleton::GetInstance();

    //Singleton s3(*s1)  // 调用拷贝构造函数

    return 0;
}

但是这样的情况下在类中又嵌套了一个类,看起来还是不美观。

方法三:auto_ptr智能指针,这个等后期再讲

方法四:这边是利用了一个static的特性,如果你第二次调用的话,那就不会再重新生成一个static对象,会用原来的。而且是一个局部静态对象,当程序结束的时候,就会调用析构函数销毁。但是这样,不是线程安全的。

#include <iostream>
using namespace std
class Singleton
{
public:
    static Singleton& GetInstance()
    {
        static Singleton instance;
        return instance;
    }
    
    ~Singleton()
    {
        cout<<"~Singleton..."<<endl;
    }


private:
    Singleton(const Singleton& other);
    Singleton& operator=(const Singleton& other)
    ~Singleton()
    {
        cout << "Singleton..." << endl;
    }

}

int main(void)
{
    Singleton& sl = Singleton::GetInstance();
    Singleton& s2 = Singleton::GetInstance();

    return 0;
}

7、const成员函数

const也可以构成重载。

#include <iostream>
using namespace std;

class Test
{
public:
    Test(int x):x_(x)
    {
        
    }

    int GetX() const
    {
        cout << "const GetX ..." << endl;
        //x_ = 100;  // 这样会报错
        return x_;
    }

    int GetX()
    {
        cout << "GetX ..." << endl;
        return x_;
    }
private:
    int x_;
}

int main(void)
{
    return 0;
}

8、const对象

因为const对象不允许修改,所以如果const对象允许调用非const成员函数,那就有被修改的风险。

#include <iostream>
using namespace std;

class Test
{
public:
    Test(int x):x_(x)
    {
        
    }

    int GetX() const
    {
        cout << "const GetX ..." << endl;
        //x_ = 100;  // 这样会报错
        return x_;
    }

    int GetX()
    {
        cout << "GetX ..." << endl;
        return x_;
    }
private:
    int x_;
}

int main(void)
{
    const Test t(10);
    t.GetX();

    Test t2(20);
    t2.GetX();
    return 0;
}

9、mutable

#include <iostream>
using namespace std;

class Test
{
public:
    Test(int x):x_(x)
    {
        
    }

    int GetX() const
    {
        cout << "const GetX ..." << endl;
        //x_ = 100;  // 这样会报错
        return x_;
    }

    int GetX()
    {
        cout << "GetX ..." << endl;
        return x_;
    }

    void OutPut() const
    {
        cout << "x = " << x_ << endl;
        outputTimes_++;
    }

    int GetOutputTimes() const
    {
        return outputTimes_;
    }
private:
    int x_;

    mutable int outputTimes_;
}

int main(void)
{
    const Test t(10);
    t.GetX();

    Test t2(20);
    t2.GetX();

    t.Output();
    t.Output();
    cout << t.GetOutputTimes() << endl;
    return 0;
}

10、const总结

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

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

相关文章

Unity3D插件开发教程(二):制作批处理工具

Unity3D插件开发教程&#xff08;二&#xff09;&#xff1a;制作批处理工具 文章来源&#xff1a;Unity3D插件开发教程&#xff08;二&#xff09;&#xff1a;制作批处理工具 - 知乎 (zhihu.com) 声明&#xff1a; 题图来自于Gratisography | Free High Resolution Pictures…

区块链的运行原理与演示

目录 前言 具体演示 1、在浏览器中输入区块链演示网址&#xff1a; 2、创建新区块 3、篡改区块信息使其无效 4、新增P2P 网络节点。 5、节点连接。 6、区块信息同步 总结 前言 区块链系统是由一系列分布在全球各地的分布式节点组成的。这些节点互不隶属&#xff0c;通过…

目标检测基础初步学习

目标检测&#xff08;Object Detection&#xff09; 目标检测任务说明 在动手学习深度学习中对目标检测任务有如下的描述。 图像分类任务中&#xff0c;我们假设图像中只有一个主要物体对象&#xff0c;我们只关注如何识别其类别。 然而&#xff0c;很多时候图像里有多个我们…

中心入侵渗透

问题1. windows登录的明文密码&#xff0c;存储过程是怎么样的&#xff1f;密文存在哪个文件下&#xff1f;该文件是否可以打开&#xff0c;并且查看到密文&#xff1f; 回答&#xff1a; Windows登录的明文密码的存储过程是&#xff1a; 当用户尝试登录Windows时&#xff0…

MM模块六(收货)

接到供应商收到的货以后&#xff0c;进行一个收货的动作 收货&#xff1a;MIGO 1.消耗物料的采购订单 数量是供应商的数量 消耗物料的采购订单&#xff0c;收进来的货物直接进入消耗&#xff0c;不会增加库存&#xff0c;所以这里没有库存地点进行选择 点击过账 收货后在采购…

ubuntu 配置用户登录失败尝试次数限制

前言&#xff1a; 通过修改pam配置来达到限制密码尝试次数&#xff01; 1&#xff1a;修改 /etc/pam.d/login 配置&#xff08;这里只是终端登录配置&#xff0c;如果还需要配置SSH远程登录限制&#xff0c;只配置下面的 /etc/pam.d/pam.d/common-auth 即可&#xff09; vim…

go-zero 实战(1)

环境准备 go 版本 go version go1.22.2 linux/amd64 goctl 安装 goctl&#xff08;官方建议读 go control&#xff09;是 go-zero微服务框架下的代码生成工具。使用 goctl 可以显著提升开发效率&#xff0c;让开发人员将时间重点放在业务开发上&#xff0c;其功能有&#xff1a…

【东山派Vision K510开发板试用笔记】WiFi配网问题

目录 概述 WiFi配网的修改 悬而未决的问题 概述 最近试用了百问网提供的东山派Vision开发板&#xff0c;DongshanPI-Vision开发板是百问网针对AI应用开发设计出来的一个RSIC-V架构的AI开发板&#xff0c;主要用于学习使用嘉楠的K510芯片进行Linux项目开发和嵌入式AI应用开发…

手撕C语言题典——返回倒数第 k 个节点(面试题)

前言 依旧力扣&#xff0c;这道题之前有做过类似的题&#xff0c;今天给一个新的思路去做&#xff0c;应对面试时候遇到的奇奇怪怪的问题 面试题 02.02. 返回倒数第 k 个节点 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/kth-node-from-end-of-list-…

英特尔LLM技术挑战记录

英特尔技术介绍&#xff1a; Flash Attention Flash Attention 是一种高效的注意力机制实现&#xff0c;旨在优化大规模 Transformer 模型中的自注意力计算。在深度学习和自然语言处理领域&#xff0c;自注意力是 Transformer 架构的核心组件&#xff0c;用于模型中不同输入元…

PMP报考条件怎么查询?如何判定自己是否符合条件?

PMP报考条件在PMI官网上就可以查询&#xff0c;PMP报考条件只需要符合项目管理培训经历和项目管理经验两个方面的要求即可&#xff0c;大家可以对照下方的规定判断自己是否符合PMP报名条件 PMP报考条件 以下是PMI&#xff08;中国&#xff09;官网对于PMP报名条件的规定&…

3D点云焊缝提取 平面交线 投影

文章目录 1. 效果2. 思路3. 源码 1. 效果 2. 思路 计算点云法向量&#xff1b;计算点云位姿Pose;翻转Pose中的Z轴方向&#xff0c;使其一致&#xff1b;通过Pose的Z轴对点云进行方向过滤&#xff1b;对点云聚类&#xff1b;根据目标点云的高度提取目标点云&#xff1b;提取两块…

Unity Dotween 定位点的制作

目录 前言 一、动画预览 二、动画拆分 三、素材准备 四、曲线 OutCirc详解 五、速度分类详解 六、代码 七、组件和设置 八、作者的话 前言 我答应我的粉丝接下来更新Dotween系列&#xff0c;但是我一直没想好&#xff0c;从哪里开始讲。 Dotween的安装我就跳过了&…

Java基础之 API 字符串

文章目录 API字符串String概述创建对象 java的内存模型java的常用方法(比较)练习 API 概念: APl(Application ProgrammingInterface): 应用程序编程接口 简单理解: API就是别人已经写好的东西&#xff0c;我们不需要自己编写&#xff0c;直接使用即可。 Java API: 指的就是J…

三层交换机基本配置,动态路由链接

<Huawei>system-view //进入系统视图[Huawei]undo info-center enable //关日志[Huawei]vlan batch 2 3 //创建vlan2与3[Huawei]display vlan //检查[Huawei]interface GigabitEthernet 0/0/2 //进2口[Huawei-GigabitEthernet0/0/2]port link-type access //配置…

【STM32嵌入式系统设计与开发---传感器拓展】——1_2_蓝牙主从模块_AT配置(HC-05)

一、主机蓝牙设置 # 1、重置模块 ATORGL # 2、设置名字&#xff0c;自己随便设置 ATNAMEMaster # 3、设置连接密码&#xff0c;要和从机一样&#xff0c;密码好像可以不加双引号 ATPSWD"1234" # 4、设置为主机 ROLE 1 为主机 ROLE 0为从机 ATROLE1 # 5、设置波特…

04 FreeRTOS 队列(queue)

1、队列的特性 队列可以理解为一个传送带&#xff0c;一个流水线。 队列可以包含若干个数据&#xff1a;队列中有若干项&#xff0c;这被称为"长度"(length) 每个数据大小固定 创建队列时就要指定长度、数据大小 数据的操作采用先进先出的方法(FIFO&#xff0c;First…

Python OCR 文字检测使用模型:读光-文字检测-DBNet行检测模型-中英-通用领域

介绍 什么是OCR&#xff1f; OCR是“Optical Character Recognition”的缩写&#xff0c;中文意为“光学字符识别”。它是一种技术&#xff0c;可以识别和转换打印在纸张或图像上的文字和字符为机器可处理的格式&#xff0c;如计算机文本文件。通过使用OCR技术&#xff0c;可…

【Python安全攻防】【网络安全】一、常见被动信息搜集手段

一、IP查询 原理&#xff1a;通过目标URL查询目标的IP地址。 所需库&#xff1a;socket Python代码示例&#xff1a; import socketip socket.gethostbyname(www.163.com) print(ip)上述代码中&#xff0c;使用gethostbyname函数。该函数位于Python内置的socket库中&#xf…

xss-labs之level9、level10

一、level9 1、测试分析 尝试了之前的payload&#xff0c;发现都不行&#xff0c;看源码发现多了个strpos函数&#xff0c; strpos() 是一个在 PHP 中用于查找子串首次出现位置的函数。它接受两个参数&#xff1a;要搜索的字符串&#xff08;主字符串&#xff09;和要查找的子…