浅拷贝 静态数组的空间体现深拷贝的效果
#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;
}
拷贝构造函数一般这些情况下调用:
- 对象初始化
- 函数参数传递(值传递)
- 函数返回值(非引用类型)
- 容器类操作 // 添加对象时
// 引用传值不会调用拷贝构造函数
// 了解下新特性 移动构造函数
注意这个与拷贝构造函数的区别:
Student stu("小明");
Student stu_ = stu; // 这个 = 号是对象初始化,调用的拷贝构造函数
Student stu3("牛魔王");
stu3 = stu // 这个 = 号是赋值,调用的是 operator= 重载运算符
注意上面两个 = 的区别。
标签:10,obj,C++,stu,Student,拷贝,构造函数 From: https://www.cnblogs.com/huvjie/p/18030722