c++ 拷贝构造函数

01_拷贝构造定义

#include<iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;
struct Student{
    int id=1001;//成员变量或对象
    char *name=nullptr;
    int age=20;
    int score=99;

    Student(){cout<<"student default construction!"<<endl;}
    Student(int i,const char*n, int a,int s){
    cout<<"student "<<n<<" construction!"<<endl;
        id=i;
        if(n){
            name =(char*)malloc(strlen(n)+1);
            strcpy(name,n);
        }
        age=a;score=s;
    }
    //拷贝构造函数定义
    //拷贝构造函数的有效参数,必须是该类的对象的引用
#if 1
//  Student(Student & s,int class_no=1){
    Student(Student & s){
    cout<<"student "<<s.name<<" copy construction!"<<endl;
        id=s.id;
#if 0
        if(s.name){
            name =(char*)malloc(strlen(s.name)+1);
            strcpy(name,s.name);
        }
#else
        name = s.name;
#endif
        age=s.age;score=s.score;
    }
#endif
    ~Student()
    {
        cout<<"student "<<name<<" destructor!"<<endl;
        if(name)free(name);
    }

};//end class Student

int main()
{
    Student stu1(1001,"zhangsan",20,100);
    //调用拷贝构造函数
    //在拷贝构造函数里应该进行深拷贝
//  Student stu2(stu1);
    //此处的=不是进行原始拷贝,而是调用拷贝构造函数;
    //如果此时没有定义深拷贝的拷贝构造函数,那么就会发生double free的内存错误;因此此时进行的就是浅层对拷
    Student stu2 = stu1;
#if 0
    Student stu2;
    //此处的=是完成的原始对拷和没有定义拷贝构造函数而去用一个对象初始化另一个对象的做法一样,这种只拷贝原始数据的行为称为浅拷贝
    //浅拷贝会带来double free的内存错误
    //解决方法需要用到运算符重载
    stu2 = stu1;
#endif
    return 0;
}

02_几种初始化的方式

#include<iostream>
using namespace std;
struct student{
    string name;
    student(){} //合成构造
    student(string n){}//普通构造
    student(const char* n){}//普通构造
    student(const student &s){}//拷贝构造
    ~student(){}//析构 
};

int main()
{
    student stu1;//合成构造

    //直接初始化
    student stu5("zhangsan");
    student stu2(stu1); //拷贝构造

    //拷贝初始化
    student stu3 = stu2;//拷贝构造
    student stu6="zhangsan";//隐式转换
    //隐式转换只能发生一次
    //student tmp("zhangsan");
    //stu6(tmp);
    //const char* ->student(*)-> student(&);

    student stu4;
    stu4 = stu3;    //赋值运算

    return 0;
}

03_拷贝构造的调用时机

#include<iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;
struct Student{
    int id=1001;//成员变量或对象
    char *name=nullptr;
    int age=20;
    int score=99;

    Student(){cout<<"student default construction!"<<endl;}
    Student(int i,const char*n, int a,int s){
    cout<<"student "<<n<<" construction!"<<endl;
        id=i;
        if(n){
            name =(char*)malloc(strlen(n)+1);
            strcpy(name,n);
        }
        age=a;score=s;
    }
    //拷贝构造函数定义
    //拷贝构造函数的有效参数,必须是该类的对象的引用
#if 1
//  Student(Student & s,int class_no=1){
    Student(Student & s){
    cout<<"student "<<s.name<<" copy construction!"<<endl;
        id=s.id;
#if 1
        if(s.name){
            name =(char*)malloc(strlen(s.name)+1);
            strcpy(name,s.name);
        }
#else
        name = s.name;
#endif
        age=s.age;score=s.score;
    }
#endif
    ~Student()
    {
        cout<<"student "<<name<<" destructor!"<<endl;
        if(name)free(name);
    }

};//end class Student

int get_stu_age(Student &s)
{
    return s.age;
}
Student stu1(1001,"lisi",20,100);
Student & get_stu()
{
    return stu1;
}
//如果函数的参数和返回值是类类型的对象,那么在实参传递和函数返回时,会发生拷贝构造函数的调用;
//如果想避免此类调用带来的巨大开销,可以使用引用

int main()
{
//  Student stu2 = stu1;
    cout<<get_stu_age(stu1)<<endl;
    get_stu();

    return 0;
}

4 bak.cpp

#include<iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;
struct Student{
    int id=1001;//成员变量或对象
    char *name=nullptr;
    int age=20;
    int score=99;

    Student(){cout<<"student default construction!"<<endl;}
    Student(int i,const char*n, int a,int s){
    cout<<"student "<<n<<" construction!"<<endl;
        id=i;
        if(n){
            name =(char*)malloc(strlen(n)+1);
            strcpy(name,n);
        }
        age=a;score=s;
    }
    //拷贝构造函数定义
    //拷贝构造函数的有效参数,必须是该类的对象的引用
#if 1
    Student(Student & s){
    cout<<"student "<<s.name<<" copy construction!"<<endl;
        id=s.id;
#if 0
        if(s.name){
            name =(char*)malloc(strlen(s.name)+1);
            strcpy(name,s.name);
        }
#else
        name = s.name;
#endif
        age=s.age;score=s.score;
    }
#endif
    ~Student()
    {
        cout<<"student "<<name<<" destructor!"<<endl;
        if(name)free(name);
    }

};//end class Student

int main()
{
    Student stu1(1001,"zhangsan",20,100);
    //调用拷贝构造函数
    //在拷贝构造函数里应该进行深拷贝
//  Student stu2(stu1);
    //此处的=不是进行原始拷贝,而是调用拷贝构造函数;
    //如果此时没有定义深拷贝的拷贝构造函数,那么就会发生double free的内存错误;因此此时进行的就是浅层对拷
    Student stu2 = stu1;
#if 0
    Student stu2;
    //此处的=是完成的原始对拷和没有定义拷贝构造函数而去用一个对象初始化另一个对象的做法一样,这种只拷贝原始数据的行为称为浅拷贝
    //浅拷贝会带来double free的内存错误
    //解决方法需要用到运算符重载
    stu2 = stu1;
#endif
    return 0;
}
posted @ 2016-03-30 10:45  夜色下的港湾  Views(180)  Comments(0Edit  收藏  举报