首页 > 编程语言 >C++ 拷贝构造函数简单测试

C++ 拷贝构造函数简单测试

时间:2024-02-24 10:00:31浏览次数:28  
标签:10 obj C++ stu Student 拷贝 构造函数

浅拷贝 静态数组的空间体现深拷贝的效果

 #include <iostream>
#include <string>

using namespace std;
#define SEX_SIZE 10

class Student
{
public:
    Student(string name)
    {
        Age = 10;
        Name = new string(name);
        strcpy(Sex, "男");
    }
    ~Student()
    {
        delete Name;
    }

    void ShowInfo()
    {
        cout << "年龄:" << Age << endl;
        cout << "姓名:" << *Name << endl;
        cout << "性别:" << Sex << endl;
        cout << endl;
    }
    string* GetName()
    {
        return  Name;
    }

    string** GetNamePtr()
    {
        return &Name;
    }

    void ChangeSex(const char* sexNew, size_t size)
    {
        memcpy(Sex, sexNew, size);
    }
private:
    int Age;
    string* Name;
    char Sex[SEX_SIZE];
};


int main()
{
    Student stu("小明");
    cout << "stu:" << endl;
    stu.ShowInfo();
    cout << "----------------------" << endl;

    Student stu_(stu);
    Student* stu2 = &stu_;
    char sexNew[SEX_SIZE] = "女";
    stu2->ChangeSex(sexNew, sizeof(sexNew));

    cout << "stu2:" << endl;
    stu2->ShowInfo();
    cout << "stu:" << endl;
    stu.ShowInfo();
    cout << "----------------------" << endl;

    string nameNew("悟空");
    *stu.GetName() = nameNew;
    cout << "stu2:" << endl;
    stu2->ShowInfo();
    cout << "stu:" << endl;
    stu.ShowInfo();
    cout << "----------------------" << endl;

    // 浅拷贝,会出现 Name 两次释放的情况
    // 这里将一个置为 null
    *stu2->GetNamePtr() = nullptr;

    return 0;
}

上面进行了一次浅拷贝测试, 注意浅拷贝,同一块内存释放两次的问题。

输出:

性别:男

----------------------
stu2:
年龄:10
姓名:小明
性别:女

stu:
年龄:10
姓名:小明
性别:男

----------------------
stu2:
年龄:10
姓名:悟空
性别:女

stu:
年龄:10
姓名:悟空
性别:男

----------------------

浅拷贝,从输出可见,静态数组只有一个对象受到影响,从->。指针对象,两个都受到了影响:从小明->悟空

深拷贝

增加一个拷贝构造函数:

   Student(const Student& obj)
    {
        Age = obj.Age;
        memcpy(Sex, obj.Sex, SEX_SIZE);
        Name = new string(*obj.Name);
    }

主函数中修改一下, 深拷贝不再释放两次:

// 浅拷贝,会出现 Name 两次释放的情况
// 这里将一个置为 null
//*stu2->GetNamePtr() = nullptr;

输出:

stu:
年龄:10
姓名:小明
性别:男

----------------------
stu2:
年龄:10
姓名:小明
性别:女

stu:
年龄:10
姓名:小明
性别:男

----------------------
stu2:
年龄:10
姓名:小明
性别:女

stu:
年龄:10
姓名:悟空
性别:男

----------------------

重载 = 运算符

Student& operator=(const Student& obj)
{
    if (this == &obj) // 防止自我赋值
    {
        return *this;
    }

    Age = obj.Age;
    memcpy(Sex, obj.Sex, SEX_SIZE);
    delete Name; // 删除旧的
    Name = new string(*obj.Name);
    return *this;
}

拷贝构造函数一般这些情况下调用:

  1. 对象初始化
  2. 函数参数传递(值传递)
  3. 函数返回值(非引用类型)
  4. 容器类操作 // 添加对象时

// 引用传值不会调用拷贝构造函数
// 了解下新特性 移动构造函数

注意这个与拷贝构造函数的区别:

Student stu("小明");

Student stu_ = stu; // 这个 = 号是对象初始化,调用的拷贝构造函数
Student stu3("牛魔王");
stu3 = stu  // 这个 = 号是赋值,调用的是 operator= 重载运算符

注意上面两个 = 的区别。

标签:10,obj,C++,stu,Student,拷贝,构造函数
From: https://www.cnblogs.com/huvjie/p/18030722

相关文章

  • 【C++】【OpenCV】Visual Studio 2022 配置OpenCV
    记录一下VisualStudio配置OpenCV过程以及出现的问题本机环境:1、Windows102、VisualStudio2022 配置步骤:1、下载OpenCV(Releases·opencv/opencv·GitHub)在GitHub上下载最新的版本 2、双击打开,然后选择路径后,点击Extract 3、等待提取完成后在VisualStudio中新......
  • C++ 令人无语/好用的语法合集
    此贴用来总结一些傻逼C++语法,或者坑了我很久的写法。1、(坑)重载>,<,==时,千万不要使用pair为基的typedef!!!!!!pii的max不受你的重载影响,它自己有自己的max,然后typedef和define是相同的,基本可以看做直接替换,不会对作用域/命名做区分。2、(坑)lower_bound(..,..,{x......
  • 如何学习PYTHON(python和c++哪个难学)
    1.如何学习PYTHONPython是一门简单易学的编程语言,但想要真正掌握它需要花费不少时间和精力。我的建议是先从Python基础开始学习,掌握基本语法和常见数据结构,再逐步深入学习高级特性和应用场景。 在学习Python的过程中,https://www.fuligou8.com/noking/4006.html我们可以通过阅......
  • Windows系统下Visual Studio 2019中C++静态、动态库的封装、使用以及遇到的问题
    本篇文章主要是因为本人需要用到静、动态库的封装和使用,下面的链接关于静、动态库的封装和使用描述的非常详细:http://t.csdnimg.cn/HyTD4在按照上述封装好静、动态库之后,在VisualStudio2019使用过程中出现了“test.obj:errorLNK2019:无法解析的外部符号_createInterface......
  • C++的箭头运算符
    以前学类的时候,一个指针指向类的实例,当我们想通过指针访问某些类的成员的时候,书上直接告诉你,使用->来访问这些成员,不能用.运算符。我以前也是默默接受了这个观点,平时也没细想,今天才知道是怎么回事。string*p=string("hello");*p.empty();//错误。会先执行p.empty(),之后再......
  • 15. 三数之和C++
    先排序,再暴力找就好了。如果当前元素大于0或者前两个元素和大于0就不用找了。然后结果超时了。然后借鉴了双指针的解法,发现双指针其实就是把单向循环优化成双向循环。 classSolution{public:vector<vector<int>>threeSum(vector<int>&nums){sort(nums.beg......
  • 文件自动拷贝到桌面及设置桌面显示此电脑
    uname="$env:USERPROFILE"$uname=$uname.Substring($uname.length-8)$checkpath=test-path\\xx.xx.xxx.xxx\xx\xx\*.lnkif($checkpath-eq"True"){copy-item\\xx.xx.xxx.xxx\xx\xx\*.*-destination\\xxx\xx$\$uname......
  • C++多线程 第九章 高级线程管理
    第九章高级线程管理注意:本章内容由于教材本身问题,例子存在较大问题.请自行在理解基础上重新设计.在大多数系统上面,为每个可以与其他任务并行执行的任务分配一个单独的线程是不切实际的.但线程池允许尽量充分利用硬件提供的并发性.在线程池帮助下,可以被并发执行的任务......
  • Mounriver工程转为C++(转载)
    注:文章为内部转载。1、右键要转换为C++的工程new->other,按下图选择点击next,按下图配置,点击FINSH。2、工程转换为C++之后,原有的设置都会变成默认的,需要重新添加。上图添加头文件路径。上图添加链接脚本路径。上图使用默认的桩函数。3、添加C++初始化函数,在启动文件调......
  • C++动态内存分配探秘:new与malloc的关键差异及实例解析
     概述:在C++中,new和malloc均用于动态内存分配,但存在关键差异。new是C++运算符,能调用构造函数,返回类型明确;而malloc是C函数,仅分配内存,需手动类型转换。示例源代码生动演示了它们在构造函数调用和类型信息方面的不同。在C++中,new 和 malloc 都用于动态内存分配,但它们之间......