使用新的运算符保留动态内存

时间:2019-04-19 01:28:33

标签: c++

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

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

我希望你能理解我。

1 个答案:

答案 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