C++构造函数/析构函数/复制构造函数(深拷贝/浅拷贝)

目录

    • 1.构造函数
    • 2.析构函数
    • 3.拷贝构造函数
    • 4.深拷贝和浅拷贝
    • 5.参考内容

1.构造函数







2.析构函数







3.拷贝构造函数











4.深拷贝和浅拷贝

(1)当我们对复杂类型(结构体或者类)的对象进行初始化时,如果将对象A赋值给同类型的对象B,此时就涉及深拷贝和浅拷贝的问题;
(2)如何定义拷贝的深和浅:浅拷贝就是把类/结构体的变量原封不动的赋值,不考虑指针变量;深拷贝就是在赋值时会对指针变量做处理;
总结:对象拷贝时,对指针变量做处理的是深拷贝,不对指针变量做处理的是浅拷贝;

  示例代码如下:

class Person{
public:
	 string *name;	//姓名,是一个指针变量
    int age;			//年龄
    int gender;		//性别:0表示男,1表示女
};

Person A;
A.name ="linux";
A.age=27;
A.gender = 1;

Person B = A;

  浅拷贝的情况如下图所示:
C++构造函数/析构函数/复制构造函数(深拷贝/浅拷贝)_第1张图片

浅拷贝就是把类的变量值原封不动的复制过去,指针变量和普通变量没有任何区别;
浅拷贝的缺陷:
(1)当类的成员变量没有指针变量时,浅拷贝是没有问题的;
(2)如果类中存在指针变量,浅拷贝就会出现问题。比如上面B在拷贝A时,将A.name的值原封不动拷贝过来,导致B.name指向同一块内存,但是那块内存是A申请的,A在使用时不会考虑B,就可能存在A将内存释放掉但是B不知道,B仍然在使用那块内存,此时就会出错;

  深拷贝的情况如下图所示:
C++构造函数/析构函数/复制构造函数(深拷贝/浅拷贝)_第2张图片

(1)对指针变量做特殊处理,申请一块同样大小的内存,然后把A.name的内容拷贝过来;
总结:类的成员变量有指针变量时用深拷贝,其余情况用浅拷贝;

  深拷贝的示例代码如下:

#include 

using namespace std;

class Person{
public:
    int age;
    int gender;
    string *name;    //人的名字

    //构造函数
    Person();
    Person(string myname);
    Person(const Person &p);	//拷贝构造函数

     // 析构函数
    ~Person();

};

int main(void)
{
    //定义并初始化对象A
    Person A ("linux");
    A.age = 27;
    A.gender = 1;

	 //用A去初始化B
    Person B = A;

		//打印name的内存地址
    cout << "A.name=" << A.name  << endl <<"B.name=" << B.name << endl;

    cout << "*B.name=" << *B.name << endl;
    cout << "B.age=" << B.age << endl;
    cout << "B.gender=" << B.gender << endl;

    return 0;
}

//  默认构造函数
Person::Person()
{
    cout << "Person::Person()" << endl;
};

// 初始化name的构造函数
Person::Person(string myname)
{
    this->name = new string();
    *this->name=myname;
    cout << "Person::Person(string myname):name(myname)" << endl;
};

// 拷贝构造函数
Person::Person(const Person &p):age(p.age), gender(p.gender)
{
	 //对指针变量需要自己申请一块内存
    this->name = new string(*p.name);
    cout<< "copy constructor" << endl;
};

// 析构函数
Person::~Person()
{
    cout << "[~Person] delete this->name" << endl;
    delete (this->name);
};

  代码的执行结果如下:

root@ubuntu:# ./app 
Person::Person(string myname):name(myname)
copy constructor
A.name=0x8442020
B.name=0x8442030
*B.name=linux
B.age=27
B.gender=1
[~Person] delete this->name
[~Person] delete this->name

(1)从执行顺序来看,拷贝构造函数是用A初始化B时被调用的;
(2)从A和B的name变量(内存地址)打印来看,两者地址不相同,说明拷贝构造函数的深拷贝是有效的;
(3)拷贝构造函数中,普通变量用浅拷贝,指针变量用深拷贝;

5.参考内容

【C++入门】深拷贝和浅拷贝详解
【C++入门】拷贝构造函数详解

你可能感兴趣的:(C++,c++)