用一个已存在的对象,创建新的对象,不会调用普通构造函数, 而是调用拷贝构造函数。如果类中没有定义拷贝构造函数,编译器将提供一个默认的拷贝构造函数,它的功能是把已存在对象的成员变量,赋值给新对象的成员变量。
用一个已存在的对象,创建新的对象语法:
类名 新对象名(已存在的对象名);
类名 新对象名 = 已存在的对象名;
拷贝构造函数的调用场景
- 用一个已存在的对象,创建新的对象
- 以值传递的方式调用函数时, 如果实参为对象,会调用拷贝构造函数
void fun(Person per) {
per.show();
}
int main() {
Person per1;
per1.m_name="张三";
per1.m_age=22;
fun(per1);
return 0;
}
image.png
- 函数以值的方式返回对象时,可能会调用拷贝构造函数(linux不会,编译器做了优化)
拷贝构造函数的语法
- 访问权限必须是public
- 方法名必须和类名相同
- 没有返回值,不写void
- 如果类中定义了拷贝构造函数,编译器将不提供拷贝构造函数
类名 (contst 类名& 对象名) {}
#include <iostream>
#include<string>
using namespace std;
class Person{
public:
string m_name;
int m_age;
Person() {
m_name.clear();
m_age = 0;
cout <<"调用了Person()构造函数"<<endl;
}
//拷贝构造函数
Person(const Person& refPer) {
this->m_name = refPer.m_name;
this->m_age = refPer.m_age;
cout <<"调用了Person()拷贝构造函数"<<endl;
}
~Person() {
cout <<"调用了~Person()析构函数"<<endl;
}
void show() {
cout <<" 姓名:"<<m_name<<" 年龄:"<<m_age<<endl;
}
};
int main() {
Person per1;
per1.m_name="张三";
per1.m_age=22;
Person per2(per1);
per2.show();
// Person per3 = per1;
return 0;
}
image.png
重载拷贝构造函数
- 如果类中提供了重载的拷贝构造函数,没有默认的拷贝构造函数,编译器也会提供给默认的拷贝构造函数。
#include <iostream>
#include<string>
using namespace std;
class Person{
public:
string m_name;
int m_age;
Person() {
m_name.clear();
m_age = 0;
cout <<"调用了Person()构造函数"<<endl;
}
//拷贝构造函数
Person(const Person& refPer) {
this->m_name = refPer.m_name;
this->m_age = refPer.m_age;
cout <<"调用了Person()拷贝构造函数"<<endl;
}
//拷贝构造函数
Person(const Person& refPer, int it) {
this->m_name = refPer.m_name;
this->m_age = refPer.m_age - it;
cout <<"调用了Person()拷贝构造函数 it = "<<it<<endl;
}
~Person() {
cout <<"调用了~Person()析构函数"<<endl;
}
void show() {
cout <<" 姓名:"<<m_name<<" 年龄:"<<m_age<<endl;
}
};
int main() {
Person per;
per.m_name="张三";
per.m_age=22;
Person per2(per, 2);
per2.show();
return 0;
}
image.png
深拷贝
类的成员属性,如果有指向堆内存的指针,在拷贝构造函数里,需要深拷贝,即new出来同样大小的内存,然后把值复制到new出来的内存里。
#include <iostream>
#include<string>
using namespace std;
class Person{
public:
string m_name;
int m_age;
int * m_ptr; // 指针成员,计划使用堆内存
Person() {
m_name.clear();
m_age = 0;
m_ptr = nullptr;
cout <<"调用了Person()构造函数"<<endl;
}
//拷贝构造函数
Person(const Person& refPer) {
this->m_name = refPer.m_name;
this->m_age = refPer.m_age;
this->m_ptr = new int;
// *m_ptr = *refPer.m_ptr; 拷贝数据
memcpy(m_ptr, refPer.m_ptr, sizeof(int)); // 拷贝数据
cout <<"调用了Person()拷贝构造函数"<<endl;
}
~Person() {
delete m_ptr;
m_ptr = nullptr;
cout <<"调用了~Person()析构函数"<<endl;
}
void show() {
cout <<" 姓名:"<<m_name<<" 年龄:"<<m_age <<" m_ptr的值:"<<*m_ptr<<" m_ptr的地址:"<<m_ptr <<endl;
}
};
int main() {
Person per;
per.m_name="张三";
per.m_age=22;
per.m_ptr = new int(3);
Person per2 = per;
per2.show();
return 0;
}
网友评论