C++_类和对象(下篇)—— 内部类、匿名对象、对象拷贝时的编译器优化

news2024/9/20 10:58:44

目录

四、类和对象(下篇)

5、内部类

6、匿名对象 

7、对象拷贝时的编译器优化 


四、类和对象(下篇)

5、内部类

  1. 如果⼀个类定义在另⼀个类的内部,这个内部类就叫做内部类。内部类是⼀个独立的类,跟定义在全局相比,他只是受外部类类域限制和访问限定符限制,所以外部类定义的对象中不包含内部类。
  2. 内部类默认是外部类的友元类。
  3. 内部类本质也是⼀种封装,当A类跟B类紧密关联,A类实现出来主要就是给B类使用,那么可以考虑把A类设计为B的内部类,如果放到private/protected位置,那么A类就是B类的专属内部类,其他地方都用不了。B类受到A类域的作用影响与限制。
    #include<iostream>
    using namespace std;
    
    class A
    {
    private:
        static int _k;
        int _h = 1;
    
    public:
        class B // B默认就是A的友元
        {
        public:
            void foo(const A& a)
            {
                cout << _k << endl; //OK
                cout << a._h << endl; //OK
            }
        };
    };
    
    int A::_k = 1;
    
    int main()
    {
        cout << sizeof(A) << endl;
        A::B b;
        A aa;
        b.foo(aa);
    
        return 0;
    }

    思考:求1+2+3+...+n_牛客题霸_牛客网

上一篇博客C++_类和对象(中、下篇)中的一道牛客网站中的题目也可以使用内部类来实现:C++_类和对象(中、下篇)—— const成员函数、取地址运算符的重载、深入构造函数、类型转换、static成员、友元-CSDN博客

使用内部类的方法代码实现如下: 

class Solution 
{
    // 内部类
    class Sum
    {
    public:
        Sum()
        {
            _ret += _i;
            ++_i;
        }
    };

    static int _i;
    static int _ret;

public:
    int Sum_Solution(int n) 
    {
        // 变⻓数组
        Sum arr[n];
        return _ret;
    }
};

int Solution::_i = 1;
int Solution::_ret = 0;

        对比两种方法,内部类直接将Sum类转化为Solution类,使其成为一部分,可以直接通过友元关系直接调用,可访问对方的类,拥有权限访问。总的来说,C++的代码实现很少使用内部类这种方法。

6、匿名对象 

  1. 用类型(实参) 定义出来的对象叫做匿名对象,相比之前我们定义的类型对象名(实参) 定义出来的叫有名对象。
  2. 有名对象的生命周期是在当前函数结束之后才会结束,与匿名对象的区别是生命周期的不同。
  3. 匿名对象生命周期只在当前一行,⼀般临时定义⼀个对象当前用⼀下即可,就可以定义匿名对象。
  4. 匿名对象有参或无参的时候一定要加上括号,不然无参的时候不加括号就会变成一个定义类。
    class A
    {
    public:
        A(int a = 0)
                :_a(a)
        {
            cout << "A(int a)" << endl;
        }
    
        ~A()
        {
            cout << "~A()" << endl;
        }
    
    private:
        int _a;
    };
    
    class Solution 
    {
    public:
        int Sum_Solution(int n) 
        {
            //...
            return n;
        }
    };
    
    int main()
    {
        A aa1;
    
        // 不能这么定义对象,因为编译器⽆法识别下⾯是⼀个函数声明,还是对象定义
        //A aa1();
    
        // 但是我们可以这么定义匿名对象,匿名对象的特点不⽤取名字,
        // 但是他的⽣命周期只有这⼀⾏,我们可以看到下⼀⾏他就会⾃动调⽤析构函数
        A();
        A(1);//匿名对象
    
        A aa2(2);
    
        //没用匿名对象之前,我们需要使用两行的代码来表示,如:
        //Solution s1;
        //cout << s1.Sum_Solution(10) << end1;
        //使用之后为:
        //cout << Solution().Sum_Solution(10) << end1;
    
        // 匿名对象在这样场景下就很好⽤,当然还有⼀些其他使⽤场景,这个我们以后遇到了再说
        Solution().Sum_Solution(10);
    
        return 0;
    }

    扩展:第一,某个函数给缺省值,使用匿名对象是一个很好的选择。

    void func(A aa = A(1))
    {}

    第二,匿名对象可以引用,但是它跟静态变量一样具有常性,要加上const来修饰,但是加上const会延长临时对象的生命周期,直到引用完(即跟着r变量来走),即构造之后马上析构,现用现销毁。

    const A& r = A()

7、对象拷贝时的编译器优化 

#include<iostream>
using namespace std;

class A
{
public:
    A(int a = 0)
            :_a1(a)
    {
        cout << "A(int a)" << endl;
    }

    A(const A& aa)
            :_a1(aa._a1)
    {
        cout << "A(const A& aa)" << endl;
    }

    A& operator=(const A& aa)
    {
        cout << "A& operator=(const A& aa)" << endl;

        if (this != &aa)
        {
            _a1 = aa._a1;
        }

        return *this;
    }

    ~A()
    {
        cout << "~A()" << endl;
    }

private:
    int _a1 = 1;
};

void f1(A aa)
{}

A f2()
{
    A aa;
    return aa;
}

int main()
{
    // 传值传参
    A aa1;
    f1(aa1);
    cout << endl;

    // 隐式类型,连续构造+拷⻉构造->优化为直接构造
    f1(1);

    // ⼀个表达式中,连续构造+拷⻉构造->优化为⼀个构造
    f1(A(2));
    cout << endl;

    cout << "***********************************************" << endl;

    // 传值返回
    // 返回时⼀个表达式中,连续拷⻉构造+拷⻉构造->优化⼀个拷⻉构造 (vs2019 debug)
    // ⼀些编译器会优化得更厉害,进⾏跨⾏合并优化,直接变为构造。(vs2022 debug)
    f2();
    cout << endl;

    // 返回时⼀个表达式中,连续拷⻉构造+拷⻉构造->优化⼀个拷⻉构造 (vs2019 debug)
    // ⼀些编译器会优化得更厉害,进⾏跨⾏合并优化,直接变为构造。(vs2022 debug)
    A aa2 = f2();
    cout << endl;

    // ⼀个表达式中,连续拷⻉构造+赋值重载->⽆法优化
    aa1 = f2();
    cout << endl;

    return 0;
}
  1. 现代编译器会为了尽可能提高程序的效率,在不影响正确性的情况下会尽可能减少⼀些传参和传返回值的过程中可以省略的拷贝。
  2. 如何优化C++标准并没有严格规定,各个编译器会根据情况自行处理。当前主流的相对新⼀点的编译器对于连续⼀个表达式步骤中的连续拷贝会进行合并优化,有些更新更"激进"的编译器还会进行跨行跨表达式的合并优化。

 以下为Linux测试优化方面:

关闭优化后的直观结果:

VS2019的Debug版本优化:(比较老实)

 VS2022的Debug版本与其他版本的对比:(激进派)

编译结果的地址一致则证明是直接引用:

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

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

相关文章

基于SpringBoot+WebSocket实现地图上绘制车辆实时运动轨迹图

实现基于北斗卫星的车辆定位和轨迹图的Maven工程&#xff08;使用模拟数据&#xff09;&#xff0c;我们将使用以下技术&#xff1a; Spring Boot&#xff1a;作为后端框架&#xff0c;用来提供数据接口。Thymeleaf&#xff1a;作为前端模板引擎&#xff0c;呈现网页。Leaflet…

Agile Modbus STM32裸机移植 从机使用

本教程手把手教你实现Agile Modbus&#xff0c;照抄就能成。 并且会解读函数功能含义。 1. 引言 Agile Modbus 是一个轻量级的 Modbus 协议栈&#xff0c;可以满足用户在任何场景下的需求。 功能 支持 rtu 和 tcp 协议&#xff0c;使用纯 C 语言开发&#xff0c;不涉及任何硬…

安科瑞AIM-D100系列 光伏直流系统直流绝缘监测仪——保障光伏发电运行稳定可靠

应用场景&#xff1a;发电厂家、变电站的直流屏、电动汽车充电装置、UPS供电系统、光伏直流系统、储能系统及其它直流电网等直流系统。 随着工业的发展&#xff0c;很多用电设备和工厂设备采用直流系统供电&#xff0c;直流系统的正极和负极不接地。对于不接地&#xff08;IT&…

Axure中后台管理信息系统通用原型方案

Axure中后台管理信息系统通用原型方案中的12套模板&#xff0c;旨在帮助开发者与设计师快速搭建出标准且美观的中后台产品原型&#xff0c;提升开发效率和节省协作成本。这些模板覆盖了多样化的中后台管理系统开发需求&#xff0c;具有高度的灵活性和可定制性。 以下是对这些模…

LINUX网络编程:传输层

目录 1.端口号 1.1知名端口号 1.2注意 2.UDP协议 2.1UDP报头的格式 2.2UDP的特点 2.3UDP的缓冲区 1.端口号 端口号的作用标识一个网络中主机的一个进程。 网络之间通信无非就是&#xff0c;发送端和接受端进程之间的通信&#xff0c;所以通过ip地址找到目标主机之后&am…

城市道路街景的绿视率计算 绿化率计算(包括街景的获取)

项目背景 随着城市化进程的加快&#xff0c;城市绿地的重要性日益凸显。合理的绿化不仅能美化城市环境&#xff0c;还能净化空气、调节气候、减轻热岛效应等。因此&#xff0c;对城市道路街景的绿视率和绿化率进行量化分析&#xff0c;对于促进城市可持续发展具有重要意义。 项…

基于stm32的四旋翼无人机控制系统设计系统设计与实现

文章目录 前言资料获取设计介绍功能介绍设计程序 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师&#xff0c;一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业…

基于SpringBoot+Vue+MySQL的家乡特色推荐系统

系统展示 用户前台界面 管理员后台界面 系统背景 在当今数字化时代&#xff0c;随着旅游业的蓬勃发展和人们对本土文化探索的热情日益增长&#xff0c;一个基于SpringBoot、Vue.js与MySQL的家乡特色推荐系统应运而生。该系统旨在通过现代互联网技术&#xff0c;深度挖掘并展示各…

六、RS485实验

目录 一、RS485介绍 二、RS485通信电路 1、TP8485接口 2、485通信波形图 三、RS485相关HAL库驱动介绍 一、RS485介绍 串口是一个泛称&#xff0c;UART、RS232、RS422和RS485都遵循类似的通信时序协议&#xff0c;被通称为串口。 图1 通信时序协议 RS485是串行通信标准&am…

DBeaver 连接 mysql 报错:Public Key Retrieval is not allowed

前言 DBeaver 连接 mysql 报错&#xff1a;Public Key Retrieval is not allowed 遇到 "Public Key Retrieval is not allowed" 错误时&#xff0c;通常意味着你正在使用的身份验证方法需要加密连接&#xff0c;但是没有正确地配置客户端或服务器来支持这种加密。 解…

springbootadmin源码编译修改001_node版本管理工具nvm_任意切换node版本_没有成功记录过程---VUE工作笔记0026

由于项目需要对springbootadmin的源码进行编译和修改. 但是springbootadmin的源码编译很麻烦,主要是由于,springbootadmin-server-ui这个项目,因为他是一个前后端分离的 vue项目,而且是使用 https://github.com/coreybutler/nvm-windows/releases/tag/1.1.12 首先去下载,发…

Give azure openai an encyclopedia of information

题意&#xff1a;给 Azure OpenAI 提供一部百科全书式的信息 问题背景&#xff1a; I am currently dabbling in the Azure OpenAI service. I want to take the default model and knowledge base and now add on to it my own unique information. So, for example, for mak…

设备稳定流畅视频体验,乐鑫ESP32-S3芯片方案无线音视频传输通信

在快节奏的现代生活中&#xff0c;家庭安全和便利性成为了人们日益关注的话题。随着物联网技术的发展&#xff0c;智能家居安全系统正逐渐成为守护家庭的新选择。 家居安全如门锁和警报器&#xff0c;这些产品通过先进的传感器、摄像头和智能分析技术&#xff0c;不仅能够实时…

媒体购买指南:是什么以及如何开始

媒体购买是几乎任何企业都非常重要的一个过程&#xff0c;其中包括付费的网络广告、电视广告、音频广告、户外广告等&#xff0c;这些都是许多多渠道营销策略中的重要组成部分。然而&#xff0c;线上和线下广告远非简单之事&#xff0c;尤其是数字广告&#xff0c;随着各种平台…

Hadoop生态圈拓展内容(一)

1. Hadoop的主要部分及其作用 HDFS&#xff08;Hadoop分布式文件系统&#xff09; HDFS是一个高容错、高可靠性、高可扩展性、高吞吐率的分布式文件存储系统&#xff0c;负责海量数据的存储。 YARN&#xff08;资源管理调度系统&#xff09; YARN是Hadoop的资源管理调度系统…

【Linux】权限理解(超详细)

目录 用户 角色切换 创建和删除普通用户 权限管理 文件访问者分类&#xff08;人&#xff09; 文件类型和访问权限&#xff08;事物属性&#xff09;​编辑 文件访问权限的相关设置方法 chmod chown chgrp 问题解答 粘滞位 用户 Linux下有两种用户&#xff1a;超级…

什么是期权日内交易?怎么做日内期权策略?

今天带你了解什么是期权日内交易?怎么做日内期权策略&#xff1f;期权日内交易是一种高频、快速的交易方式&#xff0c;适合能够快速反应并进行市场分析的交易者。 50ETF期权日交易额 50ETF期权日交易额也就是常说的50ETF期权成交量&#xff0c;大多数投资者们都听过交易要买…

程序员修炼之道 11:当你编码时

不记录&#xff0c;等于没读。 这里是我阅读《程序员修炼之道》这本书的记录和思考。 编码阶段不是机械性工作&#xff0c;而是每一分钟都要做出决定——深思熟虑后的决定。如果把编码阶段当成机械性工作&#xff0c;认为这个阶段只是把设计翻译成可运行的代码段&#xff0c;这…

初识 performance_schema:轻松掌握MySQL性能监控

什么是 performance_schema performance_schema 是 MySQL 5.8 版本的一个强大功能&#xff0c;它就像是一个内置的**“性能侦探”**&#xff0c;专门用来监控和分析 MySQL 服务器的资源消耗和等待情况。有了它&#xff0c;数据库管理员和开发者就能实时了解服务器的运行状态&a…

【LLM】中国在 GPT/LLM 大模型上是否已经实现了弯道超车?

还是谈一下现状吧。中国的大模型公司与美国的大模型公司其实在数量上可能中国更多一些吧。 美国的 OpenAI&#xff1a;No.1&#xff0c;毫无疑问&#xff01;Google&#xff1a;尽管落了&#xff0c;但是依然是全球第二的实力吧&#xff1f;Meta&#xff1a;开源全靠它家的Ll…