C++学习之拷贝构造函数

 

  1. 嘛是拷贝构造函数?

    如果一个构造函数的第一个参数是’自身类‘ ‘类型’的引用,且任何额外参数都有默认值,则此构造函数是拷贝构造函数。如:

    【代码1】

    1
    2
    3
    4
    5
    6
    class A{
    public
       A();         //默认构造函数
       A(const A&); //拷贝构造函数;const可省略,但此参数几乎总是一个const的引用!
       //其他内容
    };

    拷贝构造函数会被隐式地使用,所以应该定义成explicit(explicit构造函数将限制隐式转换,只能以直接初始化的形式使用,如代码2)

    【代码2】

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    class B{
    public:
       B()=default;
       explicit B(int); //阻止了隐式转换
       B(int,int);     //explicit只对一个实参的构造函数有效,需要多个实参的构造函数不能用于执行隐式转换,故无需使用explicit
       //其他内容
    private:
       int value;
    };
    //explicit关键字只能出现在类内的构造函数声明处,在类外不能使用!如下:
    explicit B:B(int a){ //错误!!!
       value=a;
    }
    //类B的对象使用代码:
    B b();   //正确!
    B b(0);  //正确!直接初始化形式
    B b=0;   //错误!不能将explicit构造函数用于拷贝形式的初始化过程
    B b(0,0);//正确!

    当我们自己定义了一个默认构造函数后,编译器就不会为我们再定义一个合成的构造函数,但拷贝构造函数不同!即使我们自己定义的有,编译器也会我们再定义一个!一般情况下,其作用为:将其参数的成员逐个拷贝到正在创建的对象中。即编译器会从参数中给定的对象中依次将每个非static的成员拷贝到正在创建的对象中。内置类型的成员直接拷贝,类类型的成员使用其类自身的拷贝构造函数进行拷贝。

    同时,如果一个类有一个‘移动构造函数’,则拷贝初始化有时会使用移动构造函数而非拷贝构造函数来完成拷贝。

  2. 什么情况下需要使用拷贝初始化?

     

     

    【1:使用=定义变量时;如:A a=0;

    【2:将一个对象作为实参传递给一个非引用类型的形参

    【3:从一个返回类型非引用类型的函数中返回一个对象

    【4:用花括号列表初始化一个数组中的元素或一个聚合类中的成员时。

  3. ​为什么拷贝构造函数的参数必须是引用类型?

    拷贝构造函数被用来初始化’非引用类‘类型参数!如果参数不是引用类型,则为了调用拷贝构造函数,就必须拷贝其实参,但为了拷贝其实参,又需要调用拷贝构造函数,如此无限循环下去。具体例子请参照:拷贝构造函数的参数为什么必须使用引用类型

     

 



posted @ 2014-11-14 16:36  九二  阅读(484)  评论(0编辑  收藏  举报