拷贝构造函数,深拷贝与浅拷贝
一.拷贝构造函数
先直接来看代码:
#include <iostream>
#include "help.h"
using namespace std;
class Line {
public:
Line(const char *msg);//构造函数
Line(const Line& line);//拷贝构造函数
~Line();//析构函数
char* getmsg() {return _msg;}
private:
char* _msg;
};
Line::Line(const char *msg) {
_msg = new char[strlen(msg)+1];
strcpy(_msg, msg);
cout << "构造函数" << endl;
}
Line::Line(const Line& line) {
_msg = new char[strlen(line._msg) + 1];
strcpy(_msg, line._msg);
cout << "拷贝构造函数" << endl;
}
Line::~Line() {
delete []_msg;
cout << "析构函数" << endl;
}
void display(Line &line) {
cout << line.getmsg() << endl;
}
void situation1() {
Line line1("situation1");
Line line2(line1);
display(line2);
}
void situation2() {
Line line1("situation2");
Line line2 = line1;
display(line2);
}
void situation3() {
Line line1("situation3");
Line *line2 = new Line(line1);
display(*line2);
/*
注意!!!:
由于 line2是指针型,必须自己释放line2的空间,系统才会自动调用析构函数
*/
delete line2; //加上这句话之后会自己调用析构函数
}
void situation4() {
Line line1("situation4");
Line line2 = Line(line1);
display(line2);
}
int main() {
return 0;
}
/*
总结:
拷贝构造函数的基本形式为:
Classname(const Classname& obj){};
调用拷贝构造函数有以下四种情况:
1.
Classname obj1;
Classname obj2 = obj1;
2.
Classname obj1;
Classname obj2(obj1);
3.
Classname obj1;
Classname *obj2 = new Classname(obj1);//注意此处obj2指针需要自行delete,自行delete之后系统便会调用析构函数
4.
Classname obj1;
Classname obj2 = Classname(obj1);
5. T func(){
Classname T;
return T;
}
从上述例子中可以看出,在调用拷贝构造函数时,都需要进行空间的申请。
那么不用进行空间申请的拷贝呢?
*/
总结:
拷贝构造函数的基本形式为:
classname(const classname& obj){};
调用拷贝构造函数有以下四种情况:
1.
Classname obj1;
Classname obj2 = obj1;
Classname obj1;
Classname obj2(obj1);
Classname obj1;
Classname *obj2 = new Classname(obj1);//注意此处obj2指针需要自行delete,自行delete之后系统便会调用析构函数
Classname obj1;
Classname obj2 = Classname(obj1);
T func(){
Classname T;
return T;
}
从上述例子中可以看出,在调用拷贝构造函数时,都需要进行空间的申请。
二.深拷贝与浅拷贝
理解了拷贝构造函数之后,搞懂深拷贝与浅拷贝也就是易如反掌的事情了。
浅拷贝:
调用默认的拷贝构造函数
深拷贝:
调用自己写的拷贝构造函数
在 一.拷贝构造函数中,用的都是深拷贝的方法,接下来看看用浅拷贝,也就是默认的拷贝构造函数会带来哪些问题
#include <iostream>
#include "help.h"
using namespace std;
class Line {
public:
Line(const char *msg);//构造函数
Line(const Line& line);//拷贝构造函数
~Line();//析构函数
char* getmsg() {return _msg;}
private:
char* _msg;
};
Line::Line(const char *msg) {
_msg = new char[strlen(msg)+1];
strcpy(_msg, msg);
cout << "构造函数" << endl;
}
//浅拷贝构造函数
Line::Line(const Line& line) {
_msg = line._msg;
cout << "浅拷贝构造函数" << endl;
}
Line::~Line() {
delete []_msg;
_msg = NULL;
cout << "析构函数" << endl;
}
void display(Line &line) {
cout << line.getmsg() << endl;
}
int main() {
Line line1("line1");
Line line2(line1);
return 0;
}
结果是系统在运行中出错,原因很简单,看浅拷贝的代码:
//浅拷贝构造函数
Line::Line(const Line& line) {
_msg = line._msg;
cout << "浅拷贝构造函数" << endl;
}
出错原因是:line1和line2的_msg都指向了同一块堆空间,但是在析构函数的过程中却释放了两次空间,所以出错!