拷贝构造函数:以拷贝的方式初始化一个对象时,会调用拷贝构造函数。

拷贝构造函数只有一个参数,它的类型是当前类的const引用,且任何额外参数都有默认值。

#include <iostream>
#include <string>
using namespace std;

class Student{
public:
    Student(string name = "", int age = 0, float score = 0.0f);  //普通构造函数
    Student(const Student &stu);  //拷贝构造函数(声明)
public:
    void display();
private:
    string m_name;
    int m_age;
    float m_score;
};
Student::Student(string name, int age, float score): m_name(name), m_age(age), m_score(score){ }
//拷贝构造函数(定义)
Student::Student(const Student &stu){
    this->m_name = stu.m_name;
    this->m_age = stu.m_age;
    this->m_score = stu.m_score;
   
    cout<<"Copy constructor was called."<<endl;
}
void Student::display(){
    cout<<m_name<<"的年龄是"<<m_age<<",成绩是"<<m_score<<endl;
}

int main(){
    Student stu1("小白", 16, 90.5);
    Student stu2 = stu1;  //调用拷贝构造函数
    Student stu3(stu1);  //调用拷贝构造函数
    stu1.display();
    stu2.display();
    stu3.display();  
    return 0;
}

为什么必须是当前类的引用呢?

如果拷贝构造函数的参数是当前类的对象,那么在调用拷贝构造函数时,会将另外一个对象直接传递给形参,这本身就是一次拷贝,会再次调用拷贝构造函数,陷入死循环。

为什么是const引用?

原因1:拷贝构造函数的目的是用其他对象的数据来初始化当前对象,并没有期望更改其他对象的数据,使用const限制后,这个含义更加明确了。

原因2:因为const类型不能转换为非const类型,如果不是const引用做形参,就不能将const对象传递给形参。即不能使用const对象来初始化当前对象了。

默认拷贝构造函数

如果程序员没有显式的定义拷贝构造函数,那么编译器就会自动生成一个默认拷贝构造函数。

什么时候必须显式定义拷贝构造函数?

当前类持有其他资源时,如动态分配的内存、打开的文件、指向其他数据的指针、网络连接等,默认拷贝构造函数不能拷贝这些资源,此时必须显式的定义拷贝构造函数。

什么时候调用拷贝构造函数?

以拷贝的方式初始化对象时调用拷贝构造函数。

初始化对象:为对象分配内存后第一次向内存中填充数据,这个过程会调用构造函数。只要创建对象,就会调用构造函数。

初始化:在定义的同时进行赋值
赋值:定义完成以后再赋值

#include <iostream>
#include <string>
using namespace std;
class Student{
public:
    Student(string name = "", int age = 0, float score = 0.0f);  //普通构造函数
    Student(const Student &stu);  //拷贝构造函数
public:
    Student & operator=(const Student &stu);  //重载=运算符
    void display();
private:
    string m_name;
    int m_age;
    float m_score;
};
Student::Student(string name, int age, float score): m_name(name), m_age(age), m_score(score){ }
//拷贝构造函数
Student::Student(const Student &stu){
    this->m_name = stu.m_name;
    this->m_age = stu.m_age;
    this->m_score = stu.m_score;
    cout<<"Copy constructor was called."<<endl;
}
//重载=运算符
Student & Student::operator=(const Student &stu){
    this->m_name = stu.m_name;
    this->m_age = stu.m_age;
    this->m_score = stu.m_score;
    cout<<"operator=() was called."<<endl;
   
    return *this;
}
void Student::display(){
    cout<<m_name<<"的年龄是"<<m_age<<",成绩是"<<m_score<<endl;
}
int main(){
    //stu1、stu2、stu3都会调用普通构造函数Student(string name, int age, float score)
    Student stu1("小明", 16, 90.5);
    Student stu2("王城", 17, 89.0);
    Student stu3("陈晗", 18, 98.0);
   
    Student stu4 = stu1;  //调用拷贝构造函数Student(const Student &stu)
    stu4 = stu2;  //调用operator=()
    stu4 = stu3;  //调用operator=()
   
    Student stu5;  //调用普通构造函数Student()
    stu5 = stu1;  //调用operator=()
    stu5 = stu2;  //调用operator=()
   
    return 0;
}
/*运行结果:*/
Copy constructor was called.
operator=() was called.
operator=() was called.
operator=() was called.
operator=() was called.
posted on 2020-02-23 19:54  xiaobaizzZ  阅读(553)  评论(0编辑  收藏  举报