• 自定义类型转换函数operator MyInt()


    /***
     * 结论:对pass-by-value传参的常规调用,会用实参拷贝构造形参,实参与形参相互无影响;
     * 当对实参调用类型转换函数(返回形参类型),编译器会优化代码使类型转换函数返回值直接构造在调用作用域的接受对象上
    */

    1. /***
    2. * 结论:对pass-by-value传参的常规调用,会用实参拷贝构造形参,实参与形参相互无影响;
    3. * 当对实参调用类型转换函数(返回形参类型),编译器会优化代码使类型转换函数返回值直接构造在调用作用域的接受对象上
    4. */
    5. #include "stdio.h"
    6. class YourInt;
    7. void handle_yourInt(YourInt); // 友元函数必须全局声明
    8. class MyInt;
    9. class YourInt
    10. {
    11. private:
    12. int val;
    13. public:
    14. YourInt(int _val):val(_val){}
    15. YourInt(const YourInt& rhs):val(rhs.val)
    16. {
    17. printf("call YourInt(const YourInt& rhs)\n");
    18. }
    19. //YourInt(const MyInt& rhs);
    20. friend void handle_yourInt(YourInt yourInt)
    21. {
    22. printf("address of input yourInt: %lu\n",(unsigned long)&yourInt);
    23. return;
    24. }
    25. };
    26. class MyInt
    27. {
    28. public:
    29. int val;
    30. public:
    31. MyInt(int _val):val(_val){}
    32. operator YourInt() const
    33. { // MyInt到 YourInt的类型转换, 返回值类型就是operator YourInt()的YourInt
    34. printf("call operator YourInt(MyInt{%d})\n",val);
    35. YourInt rtn = YourInt(val); // 调用YourInt(int)构造
    36. printf("address of type-cast's rtn: %lu\n",(unsigned long)&rtn); // 140701897039976,140701897039976
    37. //return &rtn;// error: no viable conversion from returned value of type 'YourInt *' to function return type 'YourInt'
    38. return rtn;
    39. }
    40. operator char()const
    41. { // MyInt到char的类型转换,返回值类型就是operator char()的char
    42. return (char)val;
    43. }
    44. };
    45. //YourInt::YourInt(const MyInt& rhs):val(rhs.val)
    46. //{
    47. // printf("call YourInt(const MyInt& rhs)\n");
    48. //}
    49. int main(int argc,char* argv[])
    50. {
    51. auto func1 = []()->void{
    52. MyInt myInt(3);
    53. YourInt yourInt(myInt); // 当定义有YourInt(const MyInt&)拷贝构造函数时优先调用之,否则调用operator YourInt()类型转换
    54. printf("address of yourInt: %lu\n",(unsigned long)&yourInt);
    55. // 140701897039976,对myInt调用operator YourInt()类型转换,编译器优化后直接在调用作用域(此处yourInt)构造rtn|yourInt?
    56. };
    57. auto func2 = []()->void{
    58. MyInt myInt(4);
    59. handle_yourInt(myInt); // error: conversion from 'MyInt' to 'YourInt' is ambiguous,当同时定义有YourInt(MyInt)拷贝构造函数与operator YourInt()类型转换时会引发歧义
    60. // 140701897039976,对myInt调用operator YourInt()类型转换,编译器优化后直接在调用作用域(handle_yourInt函数内)构造rtn|形参yourInt?
    61. };
    62. auto func3 = []()->void{
    63. YourInt yourInt(5);
    64. printf("address of yourInt: %lu\n",(unsigned long)&yourInt); // 140701897039984
    65. handle_yourInt(yourInt); // 实参拷贝构造形参,形参地址140701897039976
    66. };
    67. func1();
    68. printf("...\n");
    69. func2();
    70. printf("...\n");
    71. func3();
    72. }
    73. /***
    74. call operator YourInt(MyInt{3})
    75. address of type-cast's rtn: 140701897039976
    76. address of yourInt: 140701897039976
    77. ...
    78. call operator YourInt(MyInt{4})
    79. address of type-cast's rtn: 140701897039976
    80. address of input yourInt: 140701897039976
    81. ...
    82. address of yourInt: 140701897039984
    83. call YourInt(const YourInt& rhs)
    84. address of input yourInt: 140701897039976
    85. */

  • 相关阅读:
    【面试宝典】Spring Boot 系列面试题
    SpringBoot基础之声明式事务和切面事务和编程式事务
    数据持久化技术——MP
    html 笔记:CSS
    Python正则表达式一文详解+实例代码展示
    EBS JVM 内存优化攻略
    wget编译升级故障解决
    Rust结构体和枚举
    Java基础
    vue3+ts 实现移动端拖拽交换位置
  • 原文地址:https://blog.csdn.net/HayPinF/article/details/134516602