#include <iostream> #include <string.h> using namespace std; /* run this program using the console pauser or add your own getch, system("pause") or input loop */ class Student { private: char *name; //姓名 string id; //学号 double cpp_score; //C++成绩 double math_score; //数学成绩 double Eng_score; //英语成绩 public: //此处定义构造函数 Student(char *n,string i,double c,double m,double e) { } //------------------------------------ //此处定义深拷贝构造函数 Student(Student &s) { } //--------------------------------------- //此处定义析构函数 ~Student() { } //------------------------------------ void show();//数据输出到屏幕上 }; void Student::show() { cout << "姓名:" << name << endl; cout << "ID:" << id << endl; cout << "C++成绩:" << cpp_score << endl; cout << "数学成绩:" << math_score << endl; cout << "英语成绩:" << Eng_score << endl; } int main(int argc, char** argv) { Student s1("小明","001",100,100,100); Student s2 = s1; s2.show(); return 0; }
时间: 2025-05-10 10:31:53 浏览: 31
### 实现带有深拷贝构造函数的Student类
为了实现一个包含深拷贝构造函数的 `Student` 类并正确管理内存,需要遵循以下原则:
#### 1. **深拷贝的意义**
深拷贝意味着创建一个新的对象时,不仅复制原始对象的数据成员值,还分配新的动态内存来存储这些数据副本。这避免了多个对象共享同一块动态内存的情况[^5]。
#### 2. **类设计**
假设 `Student` 类有一个字符串类型的姓名 (`name`) 和一个整数类型的年龄 (`age`)。其中,`name` 是通过指针动态分配的字符数组。以下是完整的类定义和实现:
```cpp
#include <iostream>
#include <cstring>
using namespace std;
class Student {
public:
// 构造函数
Student(const char* name, int age) : age(age), name(nullptr) {
this->setName(name);
cout << "Constructor called." << endl;
}
// 拷贝构造函数 (深拷贝)
Student(const Student& other) : age(other.age), name(nullptr) {
setName(other.name); // 使用辅助函数设置名称
cout << "Copy Constructor called." << endl;
}
// 移动构造函数 (可选,适用于 C++11 及以上版本)
Student(Student&& other) noexcept : age(other.age), name(other.name) {
other.name = nullptr; // 防止源对象释放内存
cout << "Move Constructor called." << endl;
}
// 析构函数
~Student() {
delete[] name;
name = nullptr;
cout << "Destructor called." << endl;
}
// 显示学生信息的方法
void displayInfo() const {
if (name != nullptr && strlen(name) > 0) {
cout << "Name: " << name << ", Age: " << age << endl;
} else {
cout << "Invalid student information!" << endl;
}
}
private:
char* name; // 动态分配的字符数组
int age;
// 辅助方法:用于安全地设置名字
void setName(const char* newName) {
if (newName == nullptr || strlen(newName) == 0) {
name = new char[1];
name[0] = '\0';
} else {
name = new char[strlen(newName) + 1]; // 分配足够的空间
strcpy(name, newName); // 复制字符串内容
}
}
};
int main() {
// 创建第一个学生对象
Student s1("Alice", 20);
// 使用拷贝构造函数创建第二个学生对象
Student s2(s1);
// 输出两个学生的详细信息
s1.displayInfo();
s2.displayInfo();
return 0;
}
```
---
#### 3. **代码解析**
- **构造函数**: 初始化 `age` 并调用私有方法 `setName()` 来处理动态内存分配[^4]。
- **拷贝构造函数**: 执行深拷贝逻辑,确保新对象拥有独立的动态内存区域[^3]。
- **析构函数**: 安全释放动态分配的内存资源,防止内存泄漏。
- **移动构造函数**(可选): 如果支持 C++11 或更高版本,可以通过转移语义优化性能[^2]。
---
#### 4. **注意事项**
- 当类中存在动态分配的内存时,必须提供自定义的拷贝构造函数以执行深拷贝。
- 若未显式定义拷贝构造函数,编译器会生成默认的浅拷贝版本,可能导致多对象共用一块内存的问题。
- 始终记得在析构函数中清理动态分配的资源,以免发生内存泄露。
---
阅读全文