解锁即可观看《Java工程师2022》完整课程视频

Java工程师2022

以一线互联网公司产品标准,打造适合零基础学习的全干货Java课程。选择Java,挑战高薪!

【第1周】Java基础夯实-环境搭建与语法入门
【第2周】Java基础夯实-循环、数组与方法
【第3周】Java基础进阶-面向对象之封装与继承
【第4周】Java基础进阶-面向对象之单例模式与多态
【第5周】Java基础进阶-异常、包装类、字符串与集合
【第6~7周】Java基础进阶-泛型、多线程、I/O流与综合案例
【第8~9周】数据管理必备利器-MySQL
【第10周】Java与数据库连接的桥梁
【第11周】Java高级编程
【第12周】Java必知必会框架入门-MyBatis
【第13~14周】前端编程必备三剑客——HTML、CSS与JS
【第15~16周】前端综合案例实战与前端火热框架VUE3入门
【第17周】Java Web编程急速入门
【第18周】Java Web编程进阶-常用功能与过滤器
【第19~20周】Java Web编程实战-MyBatis实现OA系统项目实战
【第21~22周】Java主流框架入门-Spring
【第23周】Java主流框架入门-Spring MVC
【第24周】Java主流框架实战-SSM开发社交网站
【第25~26周】Java主流框架实战-Spring Boot电商项目实战
【第27~28周】Java主流框架进阶实战-Spring Boot电商项目升级
【第29周】面试指导-高频面试题详解
【第30~31周】Java分布式入门
【第32周】Java微服务入门-Spring Cloud
【第33~34周】Spring Cloud微服务电商项目实战
【第35周】Zookeeper+Dubbo应用与就业指导
章节
问答
课签
笔记
评论
占位
占位

复制一个员工:赋值构造函数

上一小节中,我们介绍了构造函数和析构函数。这一小节,我们来介绍一个特殊的构造函数。

先来看一个例程:

int main(int argc,char **argv)
{
    Staff staffA;
    Staff staffB = staffA;

    return 0;
}

我们先实例化了一个对象 staffA,然后又实例化了一个对象 staffB。希望 staffB 和 staffA 具有相同的内容,或者说希望 staffB 是 staffA 的副本,那么我们一般直接在实例化的时候进行赋值就可以了。

Staff staffB = staffA;

这样做了之后,C++ 会自动为我们拷贝 staffA 中的成员变量到 staffB 的成员变量中,但是这种自动拷贝机制在某些情况下无法完成我们想要的动作,甚至有可能会出错。我们来具体看一下。

在 Staff 类中添加一些内容:

Staff.hpp

#include <string>

class Staff
{
public:
    Staff(std::string _name, int _age);
    ~Staff();

public:
    std::string name;
    int age;

    char * mem = nullptr;
};

Staff.cpp

#include "Staff.hpp"
#include <stdio.h>

Staff::Staff(std::string _name, int _age)
{
    mem = (char *)malloc(20);
    name = _name;
    age = _age;
    printf("构造函数被调用\n");
}

Staff::~Staff()
{
    if(mem != nullptr){
        free(mem);
        mem = nullptr;
    }
    printf("析构函数被调用\n");
}

在上面的代码中,在类中定义了一个指针,在构造函数中,通过 malloc 函数分配了一个 20 字节大小的堆内存,然后将这片堆内存的首地址赋值给了这个指针。在析构函数中,我们将这片堆内存释放掉。

这个时候,我们再进行一开始的操作:

Staff staffB = staffA;

先来看看 staffA 在实例化之后的内存布局:

mem 指针指向了一片 20 个字节大小的堆内存。

这个时候,再来看看执行了Staff staffB = staffA;之后,staffB 的内存布局会怎么样:

可以看到,在 C++ 默认的复制模式之下,两个对象中的 mem 指针指向了同一片内存。因为 C++ 默认的复制模式只会简单得把成员的值进行复制,面对这个 mem 指针,他只会把指针的值进行拷贝,最后的结果就是 mem 指针指向了同一片内存。

这种拷贝方式,被称之为浅拷贝。

赋值构造函数

Staff staffB = staffA;

当我们使用这种方式实例化对象的时候,并不会调用普通构造函数,而是会调用一个特殊的构造函数,被称之为赋值构造函数或者拷贝构造函数。如果我们没有写,那么就会按照浅拷贝的方式来进行复制。一个拷贝构造函数看起来就像下面这样:

Staff(const Staff & staff);

这个函数中只有一个参数 staff,表示要拷贝的对象,在我们的例子中,就是 staffA。(const 和 & 我们在后续的课程中会具体讲解)

那么我们来完整的编写一下这个函数

Staff.hpp

#include <string>

class Staff
{
public:
    Staff(std::string _name, int _age);
    Staff(const Staff & staff);
    ~Staff();

public:
    std::string name;
    int age;

    char * mem = nullptr;
};

Staff.cpp

#include "Staff.hpp"
#include <stdio.h>

Staff::Staff(std::string _name, int _age)
{
    mem = (char *)malloc(20);
    name = _name;
    age = _age;
    printf("构造函数被调用\n");
}

Staff::Staff(const Staff & staff)
{
    name = staff.name;
    age = staff.age;

    mem = (char *)malloc(20);
    memcpy(mem, staff.mem, 20);
}

Staff::~Staff()
{
    if(mem != nullptr){
        free(mem);
        mem = nullptr;
    }
    printf("析构函数被调用\n");
}

任务

?不会了怎么办
||

提问题

写笔记

公开笔记
提交
||

请验证,完成请求

由于请求次数过多,请先验证,完成再次请求

加群二维码

打开微信扫码自动绑定

您还未绑定服务号

绑定后可得到

  • · 粉丝专属优惠福利
  • · 大咖直播交流干货
  • · 课程更新,问题答复提醒
  • · 账号支付安全提醒

收藏课程后,能更快找到我哦~

使用 Ctrl+D 可将课程添加到书签

邀请您关注公众号
关注后,及时获悉本课程动态

举报

0/150
提交
取消
全部 精华 我要发布
全部 我要发布
最热 最新
只看我的

手记推荐

更多

本次提问将花费2个积分

你的积分不足,无法发表

为什么扣积分?

本次提问将花费2个积分

继续发表请点击 "确定"

为什么扣积分?