You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义C++类RemoveBook函数运算符重载错误排查求助

问题分析与解决方案

核心问题梳理

  • Book类引用成员的拷贝异常:Book类持有const Author& _author引用成员,当将Book对象存入vector时,拷贝构造会引发悬垂引用或对象构造失败,直接影响operator==的正常执行。
  • 字符串比较逻辑错误:Book的operator==中直接用_isbn == other._isbn比较的是指针地址而非字符串内容,导致相同ISBN的书籍无法被正确识别。
  • Author类静态数组重复释放:每个Author对象销毁时都会执行析构函数删除静态数组_IDs,触发重复释放内存的未定义行为。
  • Patron类成员未初始化:默认构造函数未初始化_name和_libID,使用时会产生野指针。

修正后的完整代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
#include <stdexcept>

using namespace std;

class Author {
public:
    Author() = default;
    ~Author() = default;

    Author(const string& name, const string& birthDate, int id)
        : _name(name)
        , _birthdate(birthDate)
        , _id(id)
    {
        for (int i = 0; i < _size; ++i) {
            if (id == _IDs[i]) {
                throw invalid_argument("ID Must be UNIQUE;");
            }
        }
            
        check_alloc_id_size();
        _IDs[_size++] = id;
    }

    Author(const Author& other)
        : _name(other._name)
        , _birthdate(other._birthdate)
        , _id(other._id)
    {}

    static void CleanupStaticIDs() {
        delete[] _IDs;
        _IDs = nullptr;
        _size = 0;
        _alloc_size = 1;
    }

    const string& GetBD() const { return _birthdate; }
    const string& GetName() const { return _name; }
    int GetID() const { return _id; }

private:
    string _name;
    string _birthdate;
    int _id;

    static int* _IDs;
    static int _size;
    static int _alloc_size;

    void check_alloc_id_size() {
        if (_size == _alloc_size) {
            int* temp = _IDs;
            _alloc_size *= 2;
            _IDs = new int[_alloc_size];
            for (int i = 0; i < _size; ++i) {
                _IDs[i] = temp[i];
            }
            delete[] temp;
        }
    }
};

int* Author::_IDs = new int[1];
int Author::_size = 0;
int Author::_alloc_size = 1;

class Book {
public:
    Book(const string& title, const string& isbn, int year, const Author& author)
        : _title(title)
        , _isbn(isbn)
        , _year(year)
        , _author(author)
    {}

    const string& GetTitle() const { return _title; }
    const string& GetIsbn() const { return _isbn; }
    int GetYear() const { return _year; }
    const Author& GetAuthor() const { return _author; }

    void PrintBookInfo() const {
        printf("%s\n%s\n%d\n", _title.c_str(), _isbn.c_str(), _year);
    }

    bool operator==(const Book& other) const {
        return _isbn == other._isbn;
    }

private:
    string _title;
    string _isbn;
    int _year;
    Author _author;
};

class Patron {
public:
    Patron(const string& name, const string& libID)
        : _name(name)
        , _libID(libID)
    {}

    bool operator==(const Patron& other) const {
        return _libID == other._libID;
    }

private:
    string _name;
    string _libID;
    vector<Book> _checked;
};

class Library {
public:
    void AddBook(const Book& book) {
        _books.emplace_back(book, 1);
    }

    void RemoveBook(const Book& book) {
        auto it = find_if(_books.begin(), _books.end(),
            [&book](const pair<Book, int>& elem) {
                return elem.first == book;
            });
        if (it != _books.end()) {
            _books.erase(it);
        }
    }

    void AddPatron(const Patron& patron) {
        _patrons.push_back(patron);
    }

    void RemovePatron(const Patron& patron) {
        auto it = find(_patrons.begin(), _patrons.end(), patron);
        if (it != _patrons.end()) {
            _patrons.erase(it);
        }
    }

private:
    vector<pair<Book, int>> _books;
    vector<Patron> _patrons;

    vector<Book> _checked_out_books;
    vector<Book> _available_books;
};

int main() {
    try {
        Author author1("J.K. Rowling", "1965-07-31", 1);
        Book book1("Harry Potter", "9780747532743", 1997, author1);
        
        Library lib;
        lib.AddBook(book1);
        lib.RemoveBook(book1);
    } catch (const invalid_argument& e) {
        cerr << e.what() << endl;
    }

    Author::CleanupStaticIDs();
    return 0;
}

关键修改说明

  • Book类成员调整:将const Author& _author改为值存储,彻底解决引用成员带来的拷贝构造问题,确保Book对象可安全存储和比较。
  • 字符串类型替换:把所有const char*替换为std::string,避免指针比较错误,同时简化内存管理。
  • Author静态数组修复:移除析构函数中对静态数组的删除操作,新增CleanupStaticIDs静态函数,在程序结束时手动清理,避免重复释放。
  • Patron构造函数补充:添加带参数的构造函数,确保成员变量被正确初始化,消除野指针风险。
  • RemoveBook逻辑优化:使用std::find_if替代手动循环,代码更简洁且符合STL规范。

内容的提问来源于stack exchange,提问作者crvenkapavica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 01:04:52