码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • c++隐式类型转换存在的陷阱


    目录
    • 目标代码
    • 构造函数定义的隐式类型转换
    • 分析a1
    • 分析a2
    • 分析a3

    1|0目标代码

    旨在弄懂下面的代码,明确变量a1,a2,a3在创建时编译器究竟干了那些事:

    #include<iostream> using namespace std; class A{ public: int x; A() {cout<<"A()"<<endl;} A(int i) : x(i){cout<<"A(int i)"<<endl;} A(const A &ra) : x(ra.x) {cout<<"A(const A&)"<<endl;} void operator=(const A&){cout<<"operator="<<endl;} }; int main(){ cout<<"the assignment of a1 : "<<endl; A a1; a1 = 2; cout<<"the copy initialization of a2 : "<<endl; A a2 = 2; cout<<"the direct initialization of a3 :"<<endl; A a3(a1); return 0; }

    运行结果:

    image-20220228223902552

    2|0构造函数定义的隐式类型转换

    任何只接受一个参数的构造函数,都隐式地定义了由该参数向该类型的隐式类型转换

    如A(int i)定义了一个由int向A的隐式类型转换

    所以,在任何使用A对象的地方,可以用一个int代替,此时,int会转换为一个A类型临时变量

    如对a1变量的赋值操作:

    A a1; //声明a1,a1被默认初始化 a1 = 2; //2转换为A类型的临时变量,对a1进行赋值操作

    对于隐式类型转换,需要注意两点:

    1. 隐式类型转换只允许一步转换

      class B{ public: string B_s; B() = default; B(string s) : B_s(s){}; }; int main(){ B b1,b2; //错误:char*->string->B,进行了两步转换 b1 = "hello"; b2 = string("hello"); return 0; }
    2. 接受隐式类型转换得到的对象的函数,参数传递方式必须是const引用传递

    因为c++中,一般不修改临时对象,所以临时对象只能传递给const引用。

    3|0分析a1

    A a1:

    a1进行默认初始化,调用默认构造函数A()

    a1 = 2

    1. 字面量2隐式转换为A类型的临时对象
    2. 该临时对象通过拷贝运算符operator=拷贝给a1
    3. 因为是临时对象,所以operator=必须接受const引用,否则造成编译错误

    4|0分析a2

    A a2 = 2

    1. 字面量2隐式转换为A类型的临时对象
    2. 用临时对象来拷贝初始化a2,调用拷贝构造函数A(const A&),相当于A a2(A(2))
    3. 因为是临时对象,所以拷贝构造函数A(const A&)必须接受const引用,否则造成编译错误

    特别注意

    编译器会将A a2(A(2))优化为A a2(2)

    所以程序输出“A(int i)”,而不是“A(const A&)”

    但是底层仍然调用了A(const A&),所以如果把A(const A&)改为A(A&),会造成编译错误 error: cannot bind non-const lvalue reference of type 'A&' to an rvalue of type 'A'

    这提示我们,在编写c++程序时,如果不改变对象的值,那么习惯性地采用const引用会避免许多难解的编译错误

    5|0分析a3

    用a1直接初始化a3,调用A(const A&)


    __EOF__

    本文作者:萌之上
    本文链接:https://www.cnblogs.com/timothy020/p/15948051.html
    关于博主:评论和私信会在第一时间回复。或者直接私信我。
    版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
    声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
  • 相关阅读:
    Linux账号和权限
    dreamweaver家乡主题网页设计 DIV布局个人介绍网页模板代码 DW学生个人网站制作成品下载 HTML5期末大作业
    SG90舵机的pwm信号-使用linux定时器实现控制
    Spring Security(六) —— CSRF
    上市企业管理层短视,新的视角,整理好的面板数据,stata或excel版本
    网络规划.1.扩展.IP地址规划
    【MySQL数据库原理】在MySQL Workbench界面运行SQL代码——学生管理系统
    【无标题】
    flutter 一键打出不同包名、应用名、版本名、签名、应用图标、版本号的安装包
    C++之Map与Set的模拟实现
  • 原文地址:https://www.cnblogs.com/timothy020/p/15948051.html
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号