C++之拷贝构造函数
当类对象作为形参传入函数
C++中拷贝构造函数会有几种情况被调用,第一种是当对象作为形参传入函数时,这个时候系统会调用拷贝构造函数。
#include <iostream>
#include <cstring>
using namespace std;
class CopyStructureFunction {
public:
CopyStructureFunction(int width) : w(width) {
cout << "structure function is created" << endl;
}
CopyStructureFunction(const CopyStructureFunction &obj) {
w = obj.w;
cout << "copy structure function is created" << endl;
}
~CopyStructureFunction() {
printf("析构函数已被调用\n");
};
int get_width();
private:
int w;
};
int CopyStructureFunction::get_width() {
return w;
}
//隐式调用拷贝构造函数
void get_func(CopyStructureFunction cs);
int main() {
system("chcp 65001");
int width = 10;
CopyStructureFunction cs(width);
//当对象传入函数时,拷贝构造函数被调用
get_func(cs);
int w;
int w_2;
w = cs.get_width();
cout << "普通构造函数的get_width():" << w << endl;
//显示调用拷贝构造函数
CopyStructureFunction cs_2 = cs;
w_2 = cs_2.get_width();
cout << "拷贝构造函数的get_width():" << w_2 << endl;
return 0;
}
void get_func(CopyStructureFunction cs) {
cout << "将类对象传入函数" << endl;
}
输出:
Active code page: 65001
structure function is created
copy structure function is created
将类对象传入函数
析构函数已被调用
普通构造函数的get_width():10
copy structure function is created
拷贝构造函数的get_width():10
析构函数已被调用
析构函数已被调用
get_func()就是一个典型的类对象传入函数调用拷贝函数的例子,这个时候C++会先创建一个临时变量,然后调用拷贝构造函数把对象cs的成员变量的值传给临时变量,等get_func()执行完之后,析构掉临时变量这个对象。
拷贝构造函数被调用的几个原则:
拷贝构造函数只有单个形参,这个形参常用const&修饰,是对该类类型的引用,当定义一个新对象并用同类的对象对其初始化(赋值)时,将显示调用拷贝构造函数,若将对象以值作为参数传入函数或将对象作为返回值返回,那么就会隐式调用拷贝构造函数。
若没有定义拷贝构造函数,则程序会自动创建拷贝构造函数。
必须要创建拷贝构造函数的情况:
只包含类类型成员或内置类型(但不是指针类型)成员的类,无须显式地定义拷贝构造函数也可以拷贝;有的类有一个数据成员是指针,或者是有成员表示在构造函数中分配的其他资源,这两种情况下都必须定义拷贝构造函数。
总结:
什么情况使用拷贝构造函数:
类的对象需要拷贝时,拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数:
(1)一个对象以值传递的方式传入函数体
(2)一个对象以值传递的方式从函数返回
(3)一个对象需要通过另外一个对象进行初始化。
当对象引用传入函数时,不会调用拷贝构造函数
#include <iostream>
using namespace std;
class Test {
public:
int *ptr;
//structure func
Test(int x) {
cout << "调用普通构造函数" << endl;
ptr = new int;
*ptr = x;
}
//copy structure func
Test(const Test &t) {
cout << "调用拷贝构造函数" << endl;
ptr = new int;
*ptr = *(t.ptr);
}
//delete func
~Test() {
delete ptr;
printf("deleted obj\n");
}
};
void transfer(Test &obj);
Test return_obj(Test obj);
int main() {
system("chcp 65001");
int te = 10;
Test t(te);
transfer(t);
return_obj(t);
return 0;
}
void transfer(Test &obj) {
cout << "ptr的地址:" << obj.ptr << "---ptr的值:" << *obj.ptr << endl;
}
Test return_obj(Test obj) {
return obj;
}
输出:
Active code page: 65001
调用普通构造函数
ptr的地址:0xe71750---ptr的值:10
调用拷贝构造函数
调用拷贝构造函数
deleted obj
deleted obj
deleted obj
析构函数调用了三次,分别是析构掉普通构造函数,析构掉return_obj()当对象以值作为参数传入时调用的拷贝构造函数,析构掉当对象作为函数返回值时调用的拷贝构造函数。