构造函数和析构函数是特殊函数,构造函数的主要作用是初始化类成员变量,析构函数恰恰相反,是释放类成员变量内存。
在实例化对象时,编译器会自动调用构造和析构函数,生成一个无参的默认构造函数。
但是,自己定义构造函数后,编译器便不会自动调用构造和析构函数。
构造和析构函数格式
class demo
{
private:
/* data */
public:
demo(/* args */);
~demo();
};
demo::demo(/* args */) //构造函数
{
}
demo::~demo() //析构函数
{
}
通过上述代码可知:
构造函数没有返回值,可以有参数,函数名和类名相同。
析构函数没有返回值,也没有参数。
举例
class Person
{
private:
int num;
char *name;
public:
Person()
{
this->num = 10;
name = NULL;
}
~Person()
{
if (this->name != NULL)
{
delete []name; //释放
}
}
拷贝构造
我的理解是在实例化第一个对象后,对其进行赋值,然后再实例化第二个对象,将第一个对象中分配的空间、内容分配到第二个对象(若有不对请指正)
普通的拷贝构造:(Person Jack (Tom);)或者(Person Jack = Tom;)
注意不能用(Person Jack; Person Tom; Jack = Tom;)
Person(const Person &obj) // 拷贝构造
{
this->num = obj.num;
}
void setNum(int num)
{
this->num = num;
}
int main()
{
Person tom;
tom.setNum(666);
Person jack(tom);
}
此时jack对象的num也是666
但是当拷贝的变量有指针时,会有一种情况,比如我给tom一个名字(指针),赋值tom,然后拷贝构造至jack,此时jack.name也是tom,然后我对它修改成jack,会发现tom的name也变为了jack。
这是因为我们在拷贝时,实质上是让两个对象的指针都指向第一个tom,因此对它修改时,二者的值都会变化,这叫浅拷贝。
所以我们可以在进行构造时重新分配一个内存空间,避免这种情况,这就是深拷贝。
深拷贝
#include <iostream>
#include <string.h>
using namespace std;
class Person
{
private:
int num;
char *name;
public:
Person()
{
this->num = 10;
name = NULL;
}
~Person()
{
if (this->name != NULL)
{
//cout << "+++++" << endl;
delete []name;
}
}
Person(const Person &obj) // 拷贝构造
{
this->num = obj.num;
// 分配内存(深拷贝)
this->name = new char[20];
strcpy(this->name, obj.name);
}
void setNum(int num)
{
this->num = num;
}
void setName(char *name)
{
this->name = new char[20];
strcpy(this->name,name);
//this->name = name;
}
void getDate()
{
cout << this->name << ":" << num << endl;
}
};
int main()
{
Person tom;
char name1[] = {"tom"};
char name2[] = {"jack"};
char *p = name1, *fp = name2;
tom.setNum(666);
tom.setName(p);
tom.getDate();
Person jack(tom);
jack.getDate();
jack.setName(fp);
tom.getDate();
jack.getDate();
}
浅拷贝和深拷贝的主要差别就是有没有分配内存空间,要特别注意这一点。