使用重载加法运算符的困难

Difficulty with using an overloaded addition operator

本文关键字:运算符 重载      更新时间:2023-10-16

这是我的程序。我必须使类型的学生对象,然后有学生"签出"一个项目。我正在使用一个重载的加法运算符来让用户签出该项。

main.cpp:

#include <iostream>
#include "Student.h"
using namespace std;
int main() {
    Student s(54000, "JOHN", "DOE");
    cout << "main:" << endl << (s + "Frisbee") << endl << endl;
    system("pause");
    return 0;
}

我在头文件中定义了所有的类定义,以尽量保持程序的最小化和简化。

Student.h:

#ifndef STUDENT_H
#define STUDENT_H
#include <fstream>
#include <string>
#include <iostream>
using namespace std;
class Student {
public:
    string firstName;
    string lastName;
    int id;
    int itemsCheckedOut;
    int size;
    string *array;
    Student(int id = 0, string firstName = "", string lastName = "") {
        Student::firstName = firstName;
        Student::lastName = lastName;
        Student::id = id;
        itemsCheckedOut = 0;
        size = 10;
        array = new string[size];
    }
    Student(const Student &other) {
        itemsCheckedOut = other.itemsCheckedOut;
        array = new string[itemsCheckedOut];
        for (int i = 0; i < itemsCheckedOut; i++) {
            array[i] = other.array[i];
        }
    }
    ~Student() {
        delete[] array;
        array = NULL;
    }
    Student &operator=(const Student &rhs) {
        if (this != &rhs) {
            firstName = rhs.firstName;
            lastName = rhs.lastName;
            id = rhs.id;
            itemsCheckedOut = rhs.itemsCheckedOut;
            delete[] array;
            array = new string[size];
            for (int i = 0; i < itemsCheckedOut; i++) {
                array[i] = rhs.array[i];
            }
        }
        return *this;
    }
    void CheckOut(const string &item) {
        array[itemsCheckedOut] = item;
        itemsCheckedOut++;
    }
    friend ostream &operator<<(ostream &output, const Student &student) {
        output << student.id << "  " << student.firstName << " " << student.lastName << endl;
        if (student.itemsCheckedOut != 0) {
            output << student.itemsCheckedOut;
            for (int i = 0; i < student.itemsCheckedOut; i++) {
                output << " " << student.array[i] << endl;
            }
        }
        else {
            output << 0;
        }
        return output;
    }
    const Student operator+(const string &item) {
        Student s;
        s = *this;
        s.CheckOut(item);
        cout << "class:" << endl << s << endl << endl;
        return s;
    }
};
#endif
输出:

class:
54000  JOHN DOE
1 Frisbee
main:
-858993460
1 Frisbee

可以看到,从主程序中,它输出了错误的东西。它输出的不是id后面跟着两个空格,然后是名字和姓氏,而是数字:-858993460。这一定是某种内存泄漏问题或其他什么,但我很确定我的复制构造函数,重载赋值操作符和解构函数都是正确定义的,但是你可以看看它们。

我将感激任何帮助,因为我在这里变得非常绝望。谢谢。

你的实际operator+看起来是正确的。但是您的复制构造函数和赋值操作符中存在错误,可能会导致它出错:

  • 复制构造函数不设置sizeid或名称。
  • 复制构造函数应该分配[size]项,而不是[itemsCheckedOut]项。
  • 赋值操作符不复制size
  • 赋值操作符分配一个新的数组,它的维度是旧的大小,可能会导致缓冲区溢出。
  • checkOut函数不检查它是否写入超出size的内容。它需要检测这种情况并拒绝签出,或者分配更多的空间。(上次你贴了一个关于这个项目的问题,我提到了这个)

它调用复制构造函数:

    Student(const Student &other) {
    itemsCheckedOut = other.itemsCheckedOut;
    array = new string[itemsCheckedOut];
    for (int i = 0; i < itemsCheckedOut; i++) {
        array[i] = other.array[i];
    }
}

但是你忘了复制Student的所有字段。您重写了默认的复制构造函数,因此您应该手动执行所有数据复制,如赋值操作符。

您应该将string*数组替换为std::vector。它将为您处理内存管理,使您的代码比您目前使用的手动内存管理更容易,更少出错。如果您担心在添加项时进行分配,可以保留初始大小为10(尽管对于如此小的数据大小,这应该不是问题)。