聊聊 C++ 中几类特殊成员函数

🚀 优质资源分享 🚀

学习路线指引(点击解锁)知识定位人群定位
🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
💛Python量化交易实战💛入门级手把手带你打造一个易扩展、更安全、效率更高的量化交易系统

一:背景

在 C# 中要说默认给我们定义的特殊成员函数,莫过于 构造函数,但在 C++ 中这样的特殊函数高达 6 种,有必要整合一下聊一聊。

二:特殊成员函数

1. 默认构造函数

和 C# 一样,很多书中都说,如果用户没有定义 构造函数,那么编译器会给我们定义一个,参考下面的例子:


class Person {public:string name;int age;
};int main()
{Person person;
}

接下来观察下汇编代码,看下有没有调用 默认构造函数 .

Person person;
003E32EF  lea         ecx,[person]  
003E32F2  call        Person::Person (03E15EBh)

对于 C# 学习者来说有点懵哈,定义了就相当于new了, 哈哈,这是因为 C++ 默认都是值类型哈,不过这里有必要澄清一下,并不一定所有情况都会调用 默认构造函数,因为 C++ 的汇编生成由各自 编译器 来决定,如果 编译器 觉得没必要调用 构造函数 那它就会把这一步省掉来加速性能,那什么时候不会调呢? 参考如下代码。


class Person {public:void show() {printf("show!");}
};int main()
{Person person;person.show();
}

接下来看下汇编代码。

person.show();
00E73F4F  lea         ecx,[person]  
00E73F52  call        Person::show (0E713B6h) 

可以清楚的看到,这种情况下调用 构造函数 其实没有必要,所以编译器就干脆省略了。

2. 析构函数

在 C# 中 析构函数 是由 CLR 负责管理,在 C++ 中没有托管这个概念,所以默认只能是结束作用域之前,自动调用 析构函数 释放,参考如下图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t90ftep9-1657600937158)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/63cc8aea628345de9df318465a48bad7~tplv-k3u1fbpfcp-zoom-1.image)]

3. 赋值构造函数

刚才也说到了,在 C++ 中甭管是 class 还是 struct 默认都是值类型,既然是值类型就存在stack copy 的情况,在 C# 中也是因为重写了 EqualsGetHashCode 来实现的值copy,接下来简单看下代码:


class Person {public:string name;int age;
};int main()
{Person p1 = { "jack",20 };Person p2(p1);
}

再看下 Person p2(p1) 的汇编代码。

Person p2(p1);
000F80A2  lea         eax,[p1]  
000F80A5  push        eax  
000F80A6  lea         ecx,[p2]  
000F80A9  call        Person::Person (0F15C3h) 

从汇编中可以看到调用了 Person::Person (0F15C3h) 函数,请注意,这个不是 构造函数,而是 赋值构造函数 😂, 可以调试下去看看哦。。。 截图如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BKhIIeZq-1657600937162)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/915f1e7a804840cdbe630324ef226747~tplv-k3u1fbpfcp-zoom-1.image)]

值得说一下的是,C++ 默认提供的 赋值构造函数 是浅copy,如果要实现深 copy 的话,或者有一些自定义的逻辑,建议自己实现一下。


class Person {public:string name;int age;public:Person(string name, int age) :name(name), age(age) {}Person(const Person& p) {name = p.name;age = p.age;}
};int main()
{Person p1 = { "aaaaaaaaaaaaaaaaaaaaaaaaaaa",20 };Person p2(p1);
}

4. 赋值运算符

在 C# 中 值类型 , 匿名类型, Record 都是重写过 Equals= 运算符,所以可以在这些类型上用 =, 其实在 C++ 中也可以在 class 之间进行赋值,因为编译器会帮我们重写运算符 = ,如何看出来呢?先看下代码:


class Person {public:string name;int age;public:Person(string name, int age) :name(name), age(age) {}Person(const Person& p) {name = p.name;age = p.age;}
};int main()
{Person p1 = { "aaaaaaaaaaaaaaaaaaaaaaaaaaa",20 };Person p2 = { "bbbbbbbbbbbbbbbbbbbbbbbbbbb",22 };p2 = p1;
}

最后一句的 p2 = p1 之所以能成功是因为 = 被重写了,参考汇编代码。

p2 = p1;
00FD967C  lea         eax,[p1]  
00FD967F  push        eax  
00FD9680  lea         ecx,[p2]  
00FD9683  call        Person::operator= (0FD161Dh)  

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xjf1b1OF-1657600937163)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d0a342b8fa824e3fa337e548be5b5db5~tplv-k3u1fbpfcp-zoom-1.image)]

如果需要自定义,可以自己重写。


class Person {public:string name;int age;public:Person(string name, int age) :name(name), age(age) {}Person(const Person& p) {name = p.name;age = p.age;}Person& operator = (const Person& p) {name = p.name;age = p.age;return *this;}
};int main()
{Person p1 = { "aaaaaaaaaaaaaaaaaaaaaaaaaaa",20 };Person p2 = { "bbbbbbbbbbbbbbbbbbbbbbbbbbb",22 };p2 = p1;
}

在 C++ 11 中还有特殊的 移动构造函数移动赋值构造函数, 这个还需要理解 左值 和 右值引用,篇幅有限,放到后面和大家聊了哈。

图片名称

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

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

相关文章

mysql 数据库定时备份 增量/全备份

echo 开始:$Begin 结束:$Last $GZDumpFile succ >> $LogFilecd $BakDir/daily/bin/rm -f * 2)增量备份脚本(脚本中mysql的数据存放路径是/home/mysql/data,具体根据自己的实际情况进行调整)[roottest-huanqiu ~]# vim /root…

【 Grey Hack 】万金油脚本:路由器漏洞检测

目录脚本源码用法效果及示例版本&#xff1a;Grey Hack v0.7.3618 - Alpha 脚本源码 if params.len ! 2 or params[0] "-h" or params[0] "--help" then exit("<b>Usage: "program_path.split("/")[-1]" [ip_address] […

Java开发学习(十一)----基于注解开发bean作用范围与生命周期管理

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

【 Grey Hack 】万金油脚本:从路由器获取Password

目录脚本源码用法效果及示例版本&#xff1a;Grey Hack v0.7.3618 - Alpha 脚本源码 if params.len ! 2 or params[0] "-h" or params[0] "--help" then exit("<b>Usage: "program_path.split("/")[-1]" [ip_address] […

Java的注解机制——Spring自动装配的实现原理

JDK1.5加入了对注解机制的支持&#xff0c;实际上我学习Java的时候就已经使用JDK1.6了&#xff0c;而且除了Override和SuppressWarnings(后者还是IDE给生成的……)之外没接触过其他的。 进入公司前的面试&#xff0c;技术人员就问了我关于注解的问题&#xff0c;我就说可以生成…

【一知半解】AQS

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

CentOS下Samba文件服务器的安装与配置

前言&#xff1a;文件服务器提供的服务在大多数公司或企业都会被用到&#xff0c;因为在任何的公司或企业都涉及不同职位获取不同资源文件的情况&#xff0c;这就需要根据不同职位配置相关的不同权限&#xff0c;以保证相关资源文件的安全性和保密性。一、Samba介绍&#xff1a…

Java基础软件的安装及配置及Javascript的运行

1.Jdk的安装及环境变量配置&#xff1a; &#xff08;1&#xff09;计算机-属性-高级系统设置。 &#xff08;2&#xff09;环境变量-系统变量-输入变量名JAVA_HOME-输入变量值C:\Program Files (x86)\Java\jdk1.7.0_79&#xff08;jdk安装路径&#xff09; &#xff08;3&…

【 Grey Hack 】万金油脚本:在路由器上获取shell

目录脚本源码用法效果及示例版本&#xff1a;Grey Hack v0.7.3618 - Alpha 脚本源码 if params.len ! 2 or params[0] "-h" or params[0] "--help" then exit("<b>Usage: "program_path.split("/")[-1]" [ip_address] […

面试问题整理笔记系列 一 Java容器类

虚线框表示接口&#xff1b;实线框表示实体类&#xff1b;粗线框表示最常用的实体类&#xff1b;虚线箭头表示实现了这个接口&#xff1b;实现箭头表示类可以制造箭头所指的那个类的对象。 Collection&#xff1a;只允许在每一个位置上放一个对象。它包括“以一定顺序持有一组对…

【 Grey Hack 】反向Shell

目录调查准备反向shell反向shell提权版本&#xff1a;Grey Hack v0.7.3618 - Alpha 如图&#xff0c;本案例中目标IP尚未开放常见端口 调查 通过路由器获得目标PC的用户邮箱账号和相应的Password 所用脚本介绍&#xff1a; routerpsw 准备反向shell 在本机获得root后配置r…

阈值PSI代码

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

【 Grey Hack 】万金油脚本:原地提权工具

目录脚本源码用法效果及示例版本&#xff1a;Grey Hack v0.7.3618 - Alpha 脚本源码 metaxploit include_lib("/lib/metaxploit.so") if not metaxploit thenmetaxploit include_lib(current_path "/metaxploit.so") end if if not metaxploit then ex…

android之PackageManager简单介绍

PackageManager相关 本类API是对全部基于载入信息的数据结构的封装&#xff0c;包含下面功能&#xff1a; 安装&#xff0c;卸载应用查询permission相关信息 查询Application相关信息(application&#xff0c;activity&#xff0c;receiver&#xff0c;service&#xff0c;prov…

【 Grey Hack 】万金油脚本:常见端口修改Password

目录脚本源码用法效果及示例版本&#xff1a;Grey Hack v0.7.3618 - Alpha 适用于SSH (22) 端口、FTP (21) 端口、HTTP (80) 端口、SMTP (25) 端口及3306/3307 端口等。 脚本源码 if params.len ! 2 or params[0] "-h" or params[0] "--help" then exi…

JavaScript中的原型和对象机制

1 对象相关的一些语言特性1.1 一切皆为对象JavaScript里所有的东西都是对象. 对象是属性的集合. 数字, 字符串, 布尔值等原始值是"伪对象", 它们同样拥有属性, 但是是在栈上分配并按值传递. 而其他的对象是堆上分配并按引用传递.一个很重要的概念是, 函数也是对象, 能…

【 Grey Hack 】记一次被黑经历

目录又被搞了版本&#xff1a;Grey Hack v0.7.3618 - Alpha 胆大包天的我黑进游戏内shop的IP后&#xff0c;顺着其上面的日志溯源到不少疑似其他玩家租的服务器&#xff0c;暂时没什么进展 不久后回到桌面才发现自己已经被黑入了 随后我打开日志查看记录 只看清是从我的1222…

【 Grey Hack 】加强版nmap

目录probe使用方法效果routerpcscan使用方法效果版本&#xff1a;Grey Hack v0.7.3618 - Alpha probe if params.len ! 1 or params[0] "-h" or params[0] "--help" then exit(command_info("<b>probe [IP]</b>")) if not is_va…

文档容器iOS网络编程-iCloud文档存储编程实例

在本文中,我们主要绍介文档容器的容内,自我感觉有个不错的建议和大家分享下 iCloud文档存储程编对相键值据数存储而言比较复杂&#xff0c;涉及到自定义文档类、取得iCloud文档录目、找查Ubiquity容器中的文档、保存文档和决解文档冲突等容内。 实例&#xff1a;iCloud文档存储…

CSS3之伪元素选择器和伪类选择器

伪类选择器&#xff0c;和一般的DOM中的元素样式不一样&#xff0c;它并不改变任何DOM内容。只是插入了一些修饰类的元素&#xff0c;这些元素对于用户来说是可见的&#xff0c;但是对于DOM来说不可见。伪类的效果可以通过添加一个实际的类来达到。 a:link|a:visited|a:hover|a…