拷贝构造函数调用时机探析

1.调用场景一

#include <iostram>
using namespace std;
class A
{
public:
    A(){  //无参构造函数
        cout<<"我是无参构造函数"<<endl;
    }
    A(int a){   // 有参构造函数
        this->a = a;
        cout<<"我是有参构造函数"<<endl;
    }
    A(const A &obj){
        cout<<"我是复制构造函数"<<endl;
        this-> a = obj.a + 10;
    }
    ~A(){
        cout<<"我是析构函数"<<endl;
    }
private:
    int a;
};

void Play(){
    A a1; // 调用无参构造函数
    A a2 = a1;//调用赋值构造函数,注意与下面一种情况不一样
    A a3;
    a3 = a1;//调用默认的=号运算符来实现浅拷贝
}

int main(int argc, char const *argv[])
{
    Play();
    return 0;
}

2.调用场景二

void Play()
{
    AA a1(10); //变量定义

    //赋值构造函数的第一个应用场景
    //用对象1 初始化 对象2 
    AA a2(a1); //定义变量并初始化 //括号法

    //a2 = a1; //用a1来=号给a2 编译器给我们提供的浅copy
    a2.getA();
} 
注意:初始化操作 和 等号操作 是两个不同的概念

3.调用场景三

#include <iostream>
using namespace std;
class Location
{
public:
    Location(int x=0,int y=0){
        this->x = x;
        this->y = y;
    }
    Location(const Location &p){
        x = p.x;
        y = p.y;
        cout<<"Copy_constructor called."<<endl; 
    }
    int getX(){return x;}
    int getY(){return y;}
    ~Location(){
        cout<<x<<"," <<y<<" Object destroyed."<<endl ;
    }
private:
    int x,y;
};
void func(Location p){
    cout<<"Function:"<<p.getX()<<","<<p.getY();
}
void mainplay(){
    Location A(1,2);//形参是一个元素,函数调用,会执行实参变量初始化形参变量
    func(A); //调用函数会执行拷贝构造函数,将A的副本传递给p
}

int main(int argc, char const *argv[])
{
    /* code */
    mainplay();
    return 0;
}

4.调用场景四

#include <iostream>
using namespace std;

class Location
{
public:
    Location(int x=0,int y=0){
        this->x = x;
        this->y = y;
    }
    Location(const Location &p){
        x = p.x;
        y = p.y;
        cout<<"Copy_constructor called."<<endl; 
    }
    int getX(){return x;}
    int getY(){return y;}
    ~Location(){
        cout<<x<<"," <<y<<" Object destroyed."<<endl ;
    }
private:
    int x,y;
};

void func(Location p){
    cout<<"Function:"<<p.getX()<<","<<p.getY();
}

Location play(){
    Location A(1,2);//形参是一个元素,函数调用,会执行实参变量初始化形参变量
    return A; //到这里会执行拷贝函数,返回一个匿名对象,然后执行析构函数。
}

void mainplay(){
    //若返回的匿名对象,赋值给另外一个同类型的对象,那么匿名对象会被析构   //注意:赋值(调用=号运算符)与初始化(调用构造函数)时两码事
    Location B;
    B = g(); //用匿名对象赋值给对象B,然后析构匿名对象
    //若返回的匿名对象,来初始化另外一个同类型的对象,那么匿名对象会直接转成新的对象
    Location B = g(); //不会析构,也不会调用构造函数
}

int main(int argc, char const *argv[])
{
    /* code */
    mainplay();
    return 0;
}

 

posted @ 2017-08-10 16:22  看雪。  阅读(479)  评论(0)    收藏  举报