我正在学习新的运算符,但我有下一个问题: 当我添加新主题时,我想保留新的内存,如果这样做,我将丢失数组的所有先前内容。 因此,如果每次我想添加新主题时都必须保留内存,该怎么办?或者换句话说,我如何保留内存而不丢失之前的知识?
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
using namespace std;
class Subject {
public:
Subject() { m_name = "";
m_hours = 0;
}
string getName() { return m_name; }
int getHours() { return m_hours; }
void setName(string name) { m_name = name; }
void setHours(int hours) { m_hours = hours; }
private:
string m_name;
int m_hours;
};
class Person {
private:
string m_name;
int m_age;
Subject *m_subjects;
int m_nSubjects;
public:
Person() {
m_name = "";
m_age = 0;
m_nSubjects = 0;
}
~Person() {
}
string getName() { return m_name; }
int getAge() { return m_age; }
void setName(string name) {
m_name = name;
}
void setAge(int age) {
m_age = age;
}
void addSubject(string name, int hour);
void showSubjects();
};
void Person::addSubject(string name, int hours) {
m_subjects = new Subject[m_nSubjects+1]; *the problem is here, all the previus content is lost*
m_subjects[m_nSubjects].setName(name);
m_subjects[m_nSubjects].setHours(hours);
m_nSubjects++;
}
void Person::showSubjects() {
for (int i = 0; i < m_nSubjects; i++) {
cout << m_subjects[i].getName();
cout << "\n";
cout << m_subjects[i].getHours();
}
}
int main() {
int nSubjects;
string name;
int hours;
Person person1;
person1.setName("Name 1");
person1.setAge(30);
cout << "Subjects to add: ";
cin >> nSubjects;
for (int i = 0; i < nSubjects; i++) {
cout << "Name of subject: " << "\n" << endl;
cin >> name;
cout << "Hours: " << "\n" << endl;
cin >> hours;
person1.addSubject(name, hours);
}
person1.showSubjects();
system("pause");
return 0;
}
我希望你能理解我。
答案 0 :(得分:2)
您需要先将现有数据复制到新阵列,然后再替换先前的阵列(泄漏的是BTW),例如:
void Person::addSubject(string name, int hours) {
Subject *new_subjects = new Subject[m_nSubjects+1];
for(int i = 0; i < m_nSubjects; ++i) {
new_subjects[i] = m_subjects[i];
}
new_subjects[m_nSubjects].setName(name);
new_subjects[m_nSubjects].setHours(hours);
delete[] m_subjects;
m_subjects = new_subjects;
m_nSubjects++;
}
您还需要释放Person
析构函数中的当前数组,以免泄漏:
~Person() {
delete[] m_subjects;
}
此外,您还需要向Person
添加一个复制构造函数和一个复制赋值运算符,以避免将来出现多个{{1} }对象将内存中的同一数组共享给另一个Person
:
Person
而且,如果您使用的是C ++ 11或更高版本,则还应该(可选)向Person(const Person &src) {
m_name = src.m_name;
m_age = src.m_age;
m_nSubjects = src.m_nSubjects;
m_subjects = new Subject[m_nSubjects];
for (int i = 0; i < m_nSubjects; ++i) {
m_subjects[i] = src.m_subjects[i];
}
}
Person& operator=(const Person &rhs) {
if (&rhs != this) {
Person copy(rhs);
std::swap(m_name, copy.m_name);
std::swap(m_age, copy.m_age);
std::swap(m_nSubjects, copy.m_nSubjects);
std::swap(m_subjects, copy.m_subjects);
}
return *this;
}
添加 move构造函数和 move赋值运算符 ,也:
Person
有关更多详细信息,请参见Rule of 3/5/0。
一个更好的解决方案是改用Person(Person &&src) {
m_name = std::move(src.m_name);
m_age = src.m_age; src.m_age = 0;
m_nSubjects = src.m_nSubjects; src.m_nSubjects = 0;
m_subjects = src.m_subjects; src.m_subjects = nullptr;
}
Person& operator=(Person &&rhs) {
Person movedTo(std::move(rhs));
std::swap(m_name, movedTo.m_name);
std::swap(m_age, movedTo.m_age);
std::swap(m_nSubjects, movedTo.m_nSubjects);
std::swap(m_subjects, movedTo.m_subjects);
return *this;
}
,让编译器为您处理所有这些详细信息:
std::vector