【C++】构造函数和初始化列表的性能差距

news2025/2/25 12:40:39

构造函数和初始化列表的性能差距对比测试

1.说明

在C++类和对象中,你可能听到过更加推荐用初始化列表来初始化类内成员。如果类内成员是自定义类型,则只能在初始化列表中调用自定义类型的构造函数。

但初始化列表和在构造函数体内直接赋值有无性能差距呢?今天就用一份相对简单的代码来测试一下

2.测试

2.1 代码说明

首先是一个自定义类型,实现带缺省值的默认构造,拷贝构造和赋值重载这三个函数,并在内部新增打印来区分不同的函数

struct mytest {
public:
    mytest(int a = -1)
    {
        _a = a;
        cout << "mytest() " << a << endl;
    }
    mytest(const mytest& st) {
        _a = st._a;
        cout << "mytest(copy) " << st._a << endl;
    }
    mytest& operator=(const mytest& st)
    {
        _a = st._a;
        cout << "mytest operator= " << st._a << endl;
        return *this;
    }
private:
    int _a;
};

再在另外一个类中使用这个自定义类型

struct myclass {
public:
    myclass(const struct mytest& st, int b)
    {
        cout << "myclass() _b:" << _b << endl;
    }
    struct mytest _sa;
    int _b;
};

此时构造函数就有两种写法,一种是在初始化列表中初始化这个自定义类型

	myclass(const struct mytest& st, int b)
        :_sa(st),
        _b(b)
    {
        cout << "myclass() _b:" << _b << endl;
    }

另外一种是在构造函数体内通过赋值重载来初始化这个自定义类型

    myclass(const struct mytest& st, int b)
    {
         _sa = st;
         _b = b;
        cout << "myclass() _b:" << _b << endl;
    }

需要注意的是,这里的自定义类型传参采用了引用传参,并不会因此产生额外的拷贝!

主函数体如下,为了区分第一个mytest的构造函数,我在其后新增了一行输出作为分割

int main()
{
    mytest test_a(1);
    cout << "------" << endl;
    myclass test(test_a, 3);
    return 0;
}

2.2 测试

先来看看使用赋值初始化的方式,可以看到,虽然我们在初始化列表中什么都没有写,但是这里依旧调用了默认的构造函数(因为默认构造函数的缺省值给的是-1,这里能通过参数判断出来这并不是我们显式调用的构造)

调用了默认构造后,又通过赋值重载来初始化了一遍_sa,相当于两次初始化

image-20230824212849577

但如果调用初始化列表,则只会有一次拷贝构造,避免了额外的默认构造调用

image-20230824213021929

在linux下也测试过了,结果和VS2019相同

3.结论

结论就出来了:初始化列表能节省一次默认构造的调用,优化性能!

3.1 实际场景

在上面的场景中,性能差距可能并不会特别大,但是在下面的场景中可能就不一样了

struct mytest {
public:
    mytest(int sz = 1)
    {
        _str = new char[sz];
        _sz = sz;
        cout << "mytest() " << sz << endl;
    }
    mytest(const mytest& st) {
        delete _str;// 需要先销毁原视的数据
        _str = new char[st._sz]; // 再创建一个新的
        _sz = st._sz;
        //省略拷贝数据的代码
        cout << "mytest(copy) " << st._sz << endl;
    }
    mytest& operator=(const mytest& st)
    {
        delete _str;// 需要先销毁原视的数据
        _str = new char[st._sz]; // 再创建一个新的
        //省略拷贝数据的代码
        cout << "mytest& operator= " << st._sz << endl;
        return *this;
    }
private:
    char* _str;
    size_t _sz;
};

struct myclass {
public:
    myclass(const struct mytest& st, int b)
        :_sa(st),
        _b(b)
    {
         //_sa = st;
         //_b = b;
        cout << "myclass() _b:" << _b << endl;
    }
    struct mytest _sa;
    int _b;
};

在这个场景中,因为mytest自定义类型的拷贝构造涉及到了深拷贝,此时就需要将已有的空间给销毁了,再new一片新的空间出来,再将数据给拷贝过去。

白白多了一层默认构造中的new空间的+拷贝构造中delete原有空间的消耗!

如果类中需要深拷贝的成员不止一个,那性能差距就更大!

所以在C++中,一律以初始化列表优先


这里顺带提一嘴初始化列表的小坑,也算是复习;

当你使用初始化列表来初始化类内成员的时候,初始化的顺序是类内成员声明的顺序,而不是初始化列表中的顺序!这点非常重要,如果顺序不对,可能会出现使用未定义(还没有初始化完成)的参数的bug!

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

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

相关文章

亚马逊买家不能评论有哪些原因?怎么解决

如果你在亚马逊平台无法发表评论&#xff0c;那么以下几个是原因及解决方法&#xff1a; 1、账户问题&#xff1a;如果你的亚马逊账户存在异常或限制&#xff0c;可能就会被禁止或限制在产品页面上发表评论。因此你需要确保你的亚马逊账户信息是完整和准确的&#xff0c;包括联…

Web 开发 Django 管理工具

上次为大家介绍了 Django 的模型&#xff0c;通过模型就可以操作数据库&#xff0c;从而就可以改变页面的展示内容&#xff0c;那问题来了&#xff0c;我们只能通过手动编辑模型文件来配置模型吗&#xff1f;当然不是&#xff0c;Django 为我们提供了强大的工具&#xff0c;可以…

【HTML】基础语法讲解

基础语法 1. HTML 结构1.1 认识HTML标签1.2 HTML 文件基本结构1.3 标签层次结构1.4 快速生成代码框架 2. HTML 常见标签2.1 注释标签2.2 标题标签:h1-h62.3 段落标签:p2.4 <br>换行标签2.5 格式化标签2.6 图片标签&#xff1a;img2.7 超链接标签&#xff1a;a2.8 表格标签…

ETLCloud轻量级数据中台解决方案

引言 随着信息时代的到来&#xff0c;数据已经成为企业的重要资源&#xff0c;如何高效地管理、分析和应用数据变得尤为关键。然而&#xff0c;许多企业在构建数据中台时面临着高昂的成本、复杂的架构和漫长的实施周期等问题。为了解决这些挑战&#xff0c;我们推出了ETLCloud…

Pinia基本概念

Pinia基本概念 面试题&#xff1a;Pinia 相比 Vuex 有什么样的优点&#xff1f;为什么现在官方推荐使用 Pinia &#xff1f; Pinia&#xff0c;是一个 Vue 阵营的新的状态管理库&#xff0c;现在 Vue 官方已经推荐使用 Pinia 来代替 Vuex&#xff0c;或者你可以把 Pinia 看作是…

YOLOV8 win10部署笔记

文章目录 1. 背景2. 部署过程2.1 快速安装 1. 背景 看了B站许多up主的视频&#xff0c;感觉YOLOV8各方面都很优秀&#xff0c;作为新手对它的期待很大&#xff0c;于是想实际跑跑看&#xff0c;边实践&#xff0c;边学习&#xff0c;记录过程。 本篇主要是博主在windows平台上…

人工智能在机器学习中的八大应用领域

文章目录 1. 自然语言处理&#xff08;NLP&#xff09;2. 图像识别与计算机视觉3. 医疗诊断与影像分析4. 金融风险管理5. 预测与推荐系统6. 制造业和物联网7. 能源管理与环境保护8. 决策支持与智能分析结论 &#x1f389;欢迎来到AIGC人工智能专栏~探索人工智能在机器学习中的八…

[管理与领导-45]:IT基层管理者 - 个人管理 - 技术转型管理,从角色认知开始

前言&#xff1a; 在社会中&#xff0c;每个人在不同的场合扮演不同的角色&#xff0c;不同的角色带着不同的面具&#xff0c;不同的角色有的行为方式要求、说话方式要求、说话内容要求&#xff0c;个人的言行方式与不同场合下的角色相匹配&#xff0c;这就得体。每个人都是演…

从十进制到k进制:如何取出每一位数字并求和?

本篇博客中&#xff0c;我会以力扣“1837. K 进制表示下的各位数字总和”为例&#xff0c;讲解如何取出一个数k进制表示的每一位。 经过审题&#xff0c;我们发现这道题目的关键是如何理解“进制”的概念&#xff0c;尤其是如何取出k进制的每一位。我们先来回忆一下如何取出10进…

复习之web服务器--apache

PS&#xff1a;Vim复制小技巧 一、实验环境 两台虚拟机 (nodea,nodeb)配置ip搭建软件仓库关闭selinux [rootftp Desktop]# hostnamectl set-hostname nodea.westos.org [rootftp Desktop]# hostname nodea.westos.org [rootftp Desktop]# ifconfig enp1s0: flags4163<UP,B…

马原——6.对立统一规律

哲学上的矛盾是中性词&#xff1a;强弱&#xff0c;男女&#xff0c;战争与和平———— 完全是一个意思&#xff0c;只是搭配使用有所区别 原理1&#xff1a; 同一性&#xff1a; &#xff08;1&#xff09;相互依存&#xff0c;互为存在&#xff1a;老师和学生&#xff0c;没…

Linux下的系统编程——makefile入门

前言&#xff1a; 或许很多Winodws的程序员都不知道这个东西&#xff0c;因为那些Windows的IDE都为你做了这个工作&#xff0c;但我觉得要作一个好的和professional的程序员&#xff0c;makefile还是要懂。这就好像现在有这么多的HTML的编辑器&#xff0c;但如果你想成为一个专…

STL之vector(讲解迭代器失效,拷贝构造函数等现代版写法)

还是老规矩&#xff0c;直接上代码&#xff1a; #pragma once #include "riterator.hpp" #include <iostream> #include <assert.h> #include <set> #include <map> using namespace std; namespace cc {template<class T>class vect…

智安网络|监控与响应机制:建立有效的数据安全治理,保障数据安全

在当今数字化时代&#xff0c;数据安全治理对于保护组织的敏感信息和用户隐私至关重要。制定一个有效的数据安全治理策略能够明确组织对数据安全的重视&#xff0c;并确保数据得到适当的管理和保护。 1.确定数据安全治理的目标和范围 首先&#xff0c;组织需要明确数据安全治理…

蓝蓝设计ui设计公司作品--泛亚高科-光伏电站控制系统界面设计

泛亚高科(北京)科技有限公司&#xff08;以下简称“泛亚高科”&#xff09;&#xff0c;一个以实时监控、高精度数值计算为基础的科技公司&#xff0c; 自成立以来&#xff0c;组成了以博士、硕士为核心的技术团队&#xff0c;整合了华北电力大学等高校资源&#xff0c;凭借在电…

SQL注入读写文件

文章目录 条件利用SQL注入漏洞读取hosts文件查看文件读写权限安全选项允许导入导出读取hosts文件 利用SQL注入漏洞写入一句话木马&#xff0c;并用蚁剑连接webshell写入文件 条件 SQL注入有直接SQL注入&#xff0c;也有文件读写时的注入&#xff0c;后者的主要 目的在于获取web…

Android 13 - Media框架(6)- NuPlayer::Source

Source 在播放器中起着拉流&#xff08;Streaming&#xff09;和解复用&#xff08;demux&#xff09;的作用&#xff0c;Source 设计的好坏直接影响到播放器的基础功能&#xff0c;我们这一节将会了解 NuPlayer 中的通用 Source&#xff08;GenericSource&#xff09;关注本地…

Java后端面试题——Mysql篇

在Mysql中&#xff0c;如何定位慢查询呢&#xff1f; 表象&#xff1a;页面加载过慢、接口压测响应时间过长&#xff08;超过1s&#xff09; 原因&#xff1a;聚合查询 多表查询 表数据量过大查询 深度分页查询 方案&#xff1a;MySQL自带慢日志 需要在MySQL的配置文件&…

动捕设备之惯性动作捕捉,为何是数字人活动首选的动捕设备?

动捕设备是一种用于捕捉、记录和分析运动的设备&#xff0c;动捕设备可以实时追踪和记录人体的运动轨迹&#xff0c;并将这些动作捕捉数据传输到计算机上&#xff0c;赋予数字人身体姿态。而其中基于惯性动作捕捉技术的动捕设备VDSuit Full&#xff0c;是通过传感器实时测量人体…

【Hello Network】DNS协议 NAT技术 代理服务器

本篇博客简介&#xff1a;介绍DNS协议 NAT技术和代理服务器 网络各协议补充 DNSDNS背景DNS介绍DNS总结域名简介 NAT技术NAT技术背景NAT IP转换过程NAPTNAT技术缺陷NAT和代理服务器 网络协议总结应用层传输层网络层数据链路层 DNS DNS是一整套从域名映射到IP的系统 DNS背景 为…