自定义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
相关产品推荐
相关产品推荐

