zoukankan      html  css  js  c++  java
  • 【C++札记】拷贝构造函数,浅拷贝和深拷贝

    一:拷贝构造函数

    拷贝构造函数是一种特殊的构造函数,遵循如下的规则:

    1.函数名和类名一致,没有返回值。

    2.必须有一个参数,参数是本类型的一个引用变量。

    3.拷贝构造函数可以访问参数对象的任意成员(private也可以)。

    4.若自己不提供拷贝构造函数,系统会提供默认构造函数,若自己定义,系统将不再提供。

    5.系统提供的拷贝构造是浅拷贝。

    书写示例如下:

    class Student
    {
    public:
    	//构造函数
    	Student(int a, char* p);
    
    	//拷贝构造函数
    	Student(const Student& stu);
    
    	char name[32];
    	int  age;
    };

    拷贝构造函数调用

    	//调用方法1
    	Object obj1;
    	Object obj2(obj1); //或者写成:Object obj2 = obj1;
    
    	//调用方法2
    	Object  obj1;
    	Object* obj2 = new Object(obj1);

    二:浅拷贝

    浅拷贝不开辟新空间,只增加一个指针,指向原有的内存。

    #include <iostream>
    using namespace std;
    
    class Student
    {
    public:
        //构造函数
        Student(const char* myName)
        {
            int len = strlen(myName);
            name = new char[len + 1]{0};
            strcpy_s(this->name, len+1, myName);
    
            cout << "构造:" << hex << (int)name << endl;
        }
    
        //析构函数
        ~Student()
        {
            if (name)
            {
                cout << "析构:" << hex << (int)name << endl;
                delete[] name;
                name = NULL;
            }
        }
    
        //拷贝构造函数(浅拷贝)
        Student(const Student& stu)
        {
            name = stu.name;
            cout << "调用拷贝构造函数" << endl;
        }
    
    private:
        char*	name;
    };
    
    
    int main()
    {
        {
            Student stu1("hongshaorou");
    
            Student stu2(stu1);
        }
    
    }
    

    运行过程中发生了崩溃

    是因为对相同的内存地址做了两次析构导致,打印出内存地址一目了然。

    三:深拷贝

    深拷贝会开辟新的内存空间,把原有的对象复制过来。见下图:

    对上边浅拷贝代码进行修改

    class Student
    {
    public:
        //构造函数
        Student(const char* myName)
        {
            int len = strlen(myName);
            name = new char[len + 1]{0};
            strcpy_s(this->name, len+1, myName);
    
            cout << "构造:" << hex << (int)name << endl;
        }
    
        //析构函数
        ~Student()
        {
            if (name)
            {
                cout << "析构:" << hex << (int)name << endl;
                delete[] name;
                name = NULL;
            }
        }
    
        //拷贝构造函数(深拷贝)
        Student(const Student& stu)
        {
            int len = strlen(stu.name);
            name = new char[len + 1];
            strcpy_s(name, len + 1, stu.name);
            cout << "调用拷贝构造函数" << hex << (int)name<< endl;
        }
    
    private:
        char*	name;
    };

    再次运行不会发生崩溃现象,打印内存地址可见,开辟了内存空间。

  • 相关阅读:
    2017.12.16 扫雷小游戏未完成
    2017.12.15 计算机算法分析与设计 枚举
    2017.12.14 Java实现-----图书管理系统
    2017.12.13 Java中是怎样通过类名,创建一个这个类的数组
    2017.12.12 基于类的面向对象和基于原型的面向对象方式比较
    2017.12.11 String 类中常用的方法
    2017.12.10 Java写一个杨辉三角(二维数组的应用)
    2017.12.9 Java中的排序---冒泡排序、快速排序、选择排序
    spring boot compiler 版本实践
    spring boot 首次请求Controller慢
  • 原文地址:https://www.cnblogs.com/woniu201/p/11694518.html
Copyright © 2011-2022 走看看