拷贝构造函数:以拷贝的方式初始化一个对象时,会调用拷贝构造函数。
拷贝构造函数只有一个参数,它的类型是当前类的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;
}
如果拷贝构造函数的参数是当前类的对象,那么在调用拷贝构造函数时,会将另外一个对象直接传递给形参,这本身就是一次拷贝,会再次调用拷贝构造函数,陷入死循环。
原因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.
原文:https://www.cnblogs.com/xiaobaizzz/p/12353713.html