目标代码

旨在弄懂下面的代码,明确变量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;
}

运行结果:

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

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

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引用

分析a1

A a1:

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

a1 = 2

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

分析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引用会避免许多难解的编译错误

分析a3

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

最新文章

  1. UVA 1401 Remember the Word
  2. [terry笔记]IMPDP报错ORA-39083 Object type TYPE failed to create ORA-02304
  3. https,https的本地测试环境搭建,asp.net结合https的代码实现,http网站转换成https网站之后遇到的问题
  4. TOJ3649欧拉回路
  5. HDU 5699 货物运输 二分判定
  6. 2014年度辛星css教程夏季版第七节
  7. Python的Ftplib问题:UnicodeEncodeError: 'latin-1' codec can't encode characters的解决方法
  8. AsyncTask 解析
  9. [Immutable.js] Transforming Immutable Data with Reduce
  10. wordpress教程之get_posts()
  11. 读《31天学会CRM项目开发》记录3 - CRM解决方案
  12. .net core批量注入实现类
  13. 工作T-SQL备忘
  14. python常用命令
  15. mysql 入门 jdbc
  16. OpenDigg iOS开源项目月报201704
  17. Angular4.x 自定义搜索组件
  18. Nginx FastCGI的运行原理
  19. 将一个文件中的内容,在另一个文件中生成. for line in f1, \n f2.write(line)
  20. Python - 3.6 学习二

热门文章

  1. C# 季节判断
  2. 【记录一个问题】cv::cuda::BufferPool发生assert错误
  3. 集合框架-工具类-Collection-toArray方法
  4. (4)puppet常用的资源及其常用属性
  5. Typora下载安装教程(全面)
  6. 执行df hang住
  7. Java 基础02
  8. 在终端或idea编译工具中的terminal中运行mvn install 失败
  9. PyTorch 介绍 | AUTOMATIC DIFFERENTIATION WITH TORCH.AUTOGRAD
  10. Nginx网络压缩 CSS压缩 图片压缩 JSON压缩