C++之对象的使用

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总结

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用prometheus监测MySQL主从同步状态方案

说明&#xff1a;本文介绍如何使用prometheus、alertmanager监测MySQL主从&#xff0c;当从节点中断同步时&#xff0c;发送邮箱报警&#xff0c;并使用grafana将数据视图化。 结构图如下&#xff1a; 安装 &#xff08;1&#xff09;安装应用 首先&#xff0c;来安装promet…

svg画简单的立方体

开发背景 要开发一个拖拽的大屏项目&#xff0c;其中涉及到一个装饰组件&#xff0c;是一个立方体cube&#xff0c;要求颜色可以修改&#xff0c;大小可以拖拽改变。 效果如下 分析 经过我一番奇思妙想&#xff0c;决定用svg实现&#xff0c;因为对svg比较熟悉。那就先来在草…

LabVIEW中实现Trio控制器的以太网通讯

在LabVIEW中实现与Trio控制器的以太网通讯&#xff0c;可以通过使用TCP/IP协议来完成。这种方法包括配置Trio控制器的网络设置、使用LabVIEW中的TCP/IP函数库进行数据传输和接收&#xff0c;以及处理通讯中的错误和数据解析。本文将详细说明实现步骤&#xff0c;包括配置、编程…

职责链设计模式

职责链设计模式&#xff08;Chain of Responsibility Design Pattern&#xff09;是一种行为设计模式&#xff0c;使多个对象都有机会处理请求&#xff0c;从而避免请求的发送者和接收者之间的耦合。这些对象被链接成一条链&#xff0c;沿着这条链传递请求&#xff0c;直到有一…

【Vue】自动导入组件

1. 下载插件 npm install unplugin-vue-components 2. 修改vite.config.js import { fileURLToPath, URL } from node:urlimport { defineConfig } from vite import vue from vitejs/plugin-vue import Components from unplugin-vue-components/vite // 按需加载自定义组件/…

2、PHP 8.1.0-dev 后门远程命令执行漏洞复现

1、青少年ctf&#xff0c;题目PHP后门 2、页面 3、bp抓包发现PHP版本为8.1.0-dev 4、尝试使用以前爆出过的漏洞&#xff08;网上查相关案例&#xff09; User-Agentt: zerodiumvar_dump(5*5); User-Agentt: zerodiumsystem("cat /flag"); 5、查找flag User-Agentt: z…

3.游戏中自定义数据类型的解读分析

知识来源于腾讯课堂易道云 结构的解释&#xff1a; 计算机里的所有东西都是用二进制表示的&#xff0c;二进制是数字&#xff0c;我们用的阿拉伯数字0-9这个数字是十进制&#xff0c;计算机用的是二进制只有0或1&#xff0c;然后都是一堆0或1的数字&#xff0c;游戏中怎么把这…

路径规划算法--BFS

系列文章目录 文章目录 系列文章目录一、BFS二、BFS伪代码BFS与Dijkstra区别 一、BFS BFS&#xff08;Breadth First Search&#xff09;为广度优先搜索&#xff0c;是一种用于遍历或搜索树或图的搜索算法&#xff0c;适用于无权图的遍历。BFS从根节点开始&#xff0c;探索其相…

AI大模型:大数据+大算力+强算法

前言&#xff1a;好久不见&#xff0c;甚是想念&#xff0c;我是辣条&#xff0c;我又回来啦&#xff0c;兄弟们&#xff0c;一别两年&#xff0c;还有多少老哥们在呢&#xff1f; 目录 一年半没更文我干啥去了&#xff1f; AI大模型火了 人工智能 大模型的理解 为什么学习…

【Python】 Python中__slots__的妙用:提升性能与内存管理

基本原理 在Python中&#xff0c;每个类默认都会继承自object类&#xff0c;而object类在Python中是一个动态类&#xff0c;允许动态地添加属性和方法。这种灵活性使得Python在某些情况下非常强大和灵活&#xff0c;但同时也带来了一些性能和内存使用上的开销。 为了解决这个…

简化跨网文件传输摆渡过程,降低IT人员工作量

在当今数字化时代&#xff0c;IT企业面临着日益增长的数据交换需求。随着网络安全威胁的不断演变&#xff0c;网关隔离成为了保护企业内部网络不受外部威胁的重要手段。然而&#xff0c;隔离的同时&#xff0c;企业也需要在不同网络间安全、高效地传输文件&#xff0c;这就催生…

ubuntu strace命令

strace 是 Linux 系统中的一个调试工具&#xff0c;用于跟踪并记录系统调用&#xff08;system calls&#xff09;和信号&#xff08;signals&#xff09;。在 Ubuntu 中&#xff0c;strace 命令可以帮助开发者和系统管理员了解一个程序在运行时如何与操作系统内核进行交互&…

渗透测试工具Cobalt strike-1.CS介绍与配置

Cobalt Strike是一款美国Red Team开发的渗透测试神器&#xff0c;常被业界人称为CS。最近这个工具大火&#xff0c;成为了渗透测试中不可缺少的利器。其拥有多种协议主机上线方式&#xff0c;集成了提权&#xff0c;凭据导出&#xff0c;端口转发&#xff0c;socket代理&#x…

骨折分类数据集1129张10类别

数据集类型&#xff1a;图像分类用&#xff0c;不可用于目标检测无标注文件 数据集格式&#xff1a;仅仅包含jpg图片&#xff0c;每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数)&#xff1a;1129 分类类别数&#xff1a;10 类别名称:["avulsion_fracture",…

使用 RT 矩阵进行 3D 点云变换详解(基于 PCL 和 Eigen 库)

在 3D 点云处理中&#xff0c;RT 矩阵是一个常用的工具&#xff0c;用于对点云进行旋转和平移操作。本文将详细介绍 RT 矩阵的概念&#xff0c;并通过一个示例程序演示如何基于 PCL 和 Eigen 库将一帧点云进行矩阵变换再输出。 本教程的示例代码和点云数据可在 GitHub 下载。 什…

100个 Unity小游戏系列六 -Unity 抽奖游戏专题四 翻卡游戏

一、演示效果 二、知识点讲解 2.1 布局 void CreateItems(){reward_data_list reward_data_list ?? new List<RewardData>();reward_data_list.Clear();for (int i 0; i < ItemCount; i){GameObject item;if (i 1 < itemParent.childCount){item itemParent…

垂类短视频:四川鑫悦里文化传媒有限公司

垂类短视频&#xff1a;内容细分下的新媒体力量 随着移动互联网的迅猛发展和智能手机的普及&#xff0c;短视频已成为当下最受欢迎的媒介形式之一。四川鑫悦里文化传媒有限公司而在短视频领域&#xff0c;一个新兴的概念——“垂类短视频”正逐渐崭露头角&#xff0c;以其独特…

⌈ 传知代码 ⌋ 高速公路车辆速度检测软件

&#x1f49b;前情提要&#x1f49b; 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间&#xff0c;对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…

WMS仓库管理系统是怎么操作的?WMS操作流程详解

WMS 是仓库管理系统(Warehouse Management System) 的缩写。通过标准化的来料管理、拣配管理、仓库管理&#xff0c;打造实时化、透明化、可视化的仓储管理体系。一款合格的wms系统具有以下优势 提供实时可视性和自动化仓储流程&#xff0c;帮助企业更好地应对复杂的供应链网络…

python fstring教程(f-string教程)(python3.6+格式化字符串方法)

文章目录 Python F-String 教程&#xff1a;深度探究与实用指南引言基础用法什么是F-String?表达式嵌入 格式化选项小数点精度宽度与对齐数字格式化 高级用法复杂表达式调用函数多行F-String嵌套格式化 总结 Python F-String 教程&#xff1a;深度探究与实用指南 引言 在Pyt…