嵌入式工程师
3次就业内推,全流程就业服务,行业风口、政策倾斜,新晋热门高薪不内卷,越老越吃香!0基础一站式就业完整路径,抢占先发优势!
上一小节中,我们介绍了构造函数和析构函数。这一小节,我们来介绍一个特殊的构造函数。
先来看一个例程:
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 可将课程添加到书签
举报