gpt4 book ai didi

c++ - 使用 new 运算符保留动态内存

转载 作者:行者123 更新时间:2023-11-30 03:17:08 28 4
gpt4 key购买 nike

我正在学习新的运算符,我有下一个问题:我想在添加新主题时保留新内存,如果这样做,我将丢失数组的所有先前内容。那么,如果我每次想添加一个新主题时都必须保留内存,我该怎么办呢?或者说,如何保留内存而不失前世?

#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;
}

希望你能理解我。

最佳答案

您需要将现有数据复制到新数组,然后再替换之前的数组(您正在泄漏,顺便说一句),例如:

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 添加一个复制构造函数 和一个复制赋值运算符同样,为了避免将来出现多个 Person 的问题如果分配一个 Person,则对象在内存中共享相同的数组给另一个:

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;
}

而且,如果您使用的是 C++11 或更高版本,您还应该(可选地)向 Person 添加一个移动构造函数移动赋值运算符 ,也是:

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;
}

参见 Rule of 3/5/0了解更多详情。

更好的解决方案是使用 std::vector相反,让编译器为您处理所有这些细节:

#include <iostream>
#include <string>
#include <vector>
#include <limits>

class Subject {
public:
Subject() {
m_name = "";
m_hours = 0;
}

Subject(std::string name, int hours) {
m_name = name;
m_hours = hours;
}

std::string getName() const { return m_name; }
int getHours() const { return m_hours; }
void setName(std::string name) { m_name = name; }
void setHours(int hours) { m_hours = hours; }

private:
std::string m_name;
int m_hours;
};

class Person {
private:
std::string m_name;
int m_age;
std::vector<Subject> m_subjects;

public:
Person() {
m_name = "";
m_age = 0;
}

std::string getName() const { return m_name; }
int getAge() const { return m_age; }
void setName(std::string name) { m_name = name; }
void setAge(int age) { m_age = age; }
void addSubject(std::string name, int hour);
void showSubjects() const;
};

void Person::addSubject(string name, int hours) {
m_subjects.push_back(Subject(name, hours));
}

void Person::showSubjects() const {
for (std::size_t i = 0; i < m_nSubjects.size(); ++i) {
cout << m_subjects[i].getName();
cout << "\n";
cout << m_subjects[i].getHours();
}
}

int main() {
int nSubjects;
std::string name;
int hours;

Person person1;
person1.setName("Name 1");
person1.setAge(30);

std::cout << "Subjects to add: ";
std::cin >> nSubjects;
for (int i = 0; i < nSubjects; i++) {
std::cout << "Name of subject: ";
std::getline(std::cin, name);
std::cout << "Hours: ;
std::cin >> hours;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
person1.addSubject(name, hours);
}

person1.showSubjects();

std::system("pause");
return 0;
}

关于c++ - 使用 new 运算符保留动态内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55755525/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com