拷贝构造函数
一种特殊的构造函数:
- 形参是本类对象的引用
- 作用:用一个已存在的对象,初始化另一个同类的对象
- 也是构造函数的函数重载
调用:
- 通过
=
复制对象时,系统自动调用
特点:
- 函数名,同类名
- 没有返回值类型
- 只有一个参数,是同类对象的引用
class& obj
- 每个类必须有一个拷贝构造函数
- 若没有显式定义,系统会自动生成缺省的拷贝构造函数
- 缺省的拷贝构造函数,将对象的各个数据成员拷贝给被拷贝对象的各个数据成员;两个对象的内存映像是一模一样的
- 缺省拷贝构造函数按成员逐一复制的过程,自动完成
一般形式:
#include <iostream>
using namespace std;
class Point {
private:
int x, y;
public:
Point(int x_, int y_) //构造函数
{
x = x_; y = y_;
cout << "use normal constructor" << endl;
}
Point(Point& p) //拷贝构造函数
{
x = p.x; y = p.y;
cout << "use copy constructor" << endl;
}
};
int main()
{
Point p1(2, 3); //调用普通构造函数
Point p2(p1); //“代入法”调用拷贝构造函数
Point p3 = p2; //“赋值法”调用拷贝构造函数
return 0;
}
调用的三种情况
- 使用拷贝构造函数初始化对象时
Point p2(p1); //“代入法”调用拷贝构造函数
Point p3 = p2; //“赋值法”调用拷贝构造函数
- 函数形参是类的对象,调用函数时,形参与实参结合时
f1(Point p)
{
p.show();
}
int main()
{
Point p;
f1(p); //当调用函数,进行形参和实参结合时,调用拷贝构造函数
return 0;
}
- 函数的返回值是对象,函数执行完成,返回对象给调用者时
Point f2()
{
Point p(0,0);
return p;
}
int main()
{
Point p=f2(); //函数的返回值是对象,函数执行完成,返回对象给调用者时
return 0;
}
浅拷贝和深拷贝
浅拷贝:缺省的拷贝构造函数,对数据成员逐一赋值
-
实质是同一地址
-
若类有指针型数据,会产生错误
#include <iostream>
using namespace std;
class A {
private:
char* name;
int id;
public:
A(const char* name_, int id_) {
id = id_;
name = new char[strlen(name_) + 1];
if (name != 0) strcpy(name, name_);
cout << "constructing..." << name << endl;
}
~A() {
cout << "destructing..." << name << endl;
name[0] = '\0';
delete name;
}
};
int main()
{
A a1("asd", 5);
A a2 = a1;
return 0;
}
/*
output:
constructing...asd
destructing...asd
destructing...乱码
编译器报错
*/
深拷贝:显式定义的拷贝构造函数,使之不仅拷贝数据成员,而且为拷贝对象和被拷贝对象分配各自的内存空间
- 不同地址
class A {
private:
char* name;
int id;
public:
A(const char* name_, int id_) {
id = id_;
name = new char[strlen(name_) + 1];
if (name != 0) strcpy(name, name_);
cout << "constructing..." << name << endl;
}
A(A& a) {
id = a.id;
name = new char[strlen(a.name) + 1];
if (name != 0) strcpy(name, a.name);
cout << "constructing..." << name << endl;
}
~A() {
cout << "destructing..." << name << endl;
name[0] = '\0';
delete name;
}
};
/*
output:
constructing...asd
constructing...asd
destructing...asd
destructing...asd
*/