vaghxc 2024-04-28 12:31 采纳率: 88.2%
浏览 5
已结题

第三次疑惑c++图书馆问题

题目:假设图书馆里有许多书籍,每本书有书名、作者、出版社和出版日期等信息。我们可以通过该程序来实现对图书馆的管理。首先,定义一个Book类,用于表示一本书。类中需要包含书名、作者、出版社和出版日期等属性,并定义构造函数和析构函数以及其他必要的函数。接下来,定义一个Library类,用于管理图书馆的书籍。类中需要定义一个存储书籍的数组,以及对这个数组进行增加、删除、查找等操作的函数。最后,定义一个主函数,创建一个图书馆对象,并通过调用其函数,实现对图书馆中书籍的管理。

疑惑是:在查找书籍时定义的函数为什么是Book* findBook(string title) ?不理解为什么是Book*类型。还有,删除书籍和添加书籍函数并没有在函数名称或者参数列表指明它们是类的成员函数隐式地生成实现。那么在明知类外定义的删除书籍和添加书籍函数不是成员函数的情况下,为什么还能使用私有成员变量?参数中没有this指针,也没有通过引用传递类的对象。


#include <iostream>
using namespace std;
 
// Book 类定义
class Book {
private:
    string title;
    string author;
    string publisher;
    string publishDate;
 
public:
    // 构造函数
    Book(string title, string author, string publisher, string publishDate) {
        this->title = title;
        this->author = author;
        this->publisher = publisher;
        this->publishDate = publishDate;
    }
 
    // 析构函数
    ~Book() {}
 
    // 获取书名
    string getTitle() {
        return title;
    }
 
    // 获取作者
    string getAuthor() {
        return author;
    }
 
    // 获取出版社
    string getPublisher() {
        return publisher;
    }
 
    // 获取出版日期
    string getPublishDate() {
        return publishDate;
    }
};
 
// Library 类定义
class Library {
private:
    Book* books[100]; // 存储书籍的数组
    int bookCount;    // 书籍数量
 
public:
    // 构造函数
    Library() {
        bookCount = 0;
        for (int i = 0; i < 100; i++) {
            books[i] = NULL;
        }
    }
 
    // 析构函数
    ~Library() {
        for (int i = 0; i < bookCount; i++) {
            delete books[i];
        }
    }
 
    // 添加书籍
    void addBook(Book* book) {
        books[bookCount++] = book;
    }
 
    // 删除书籍
    void removeBook(string title) {
        for (int i = 0; i < bookCount; i++) {
            if (books[i]->getTitle() == title) {
                delete books[i];
                for (int j = i; j < bookCount - 1; j++) {
                    books[j] = books[j + 1];
                }
                bookCount--;
                break;
            }
        }
    }
 
    // 查找书籍
    Book* findBook(string title) {
        for (int i = 0; i < bookCount; i++) {
            if (books[i]->getTitle() == title) {
                return books[i];
            }
        }
        return NULL;
    }
 
    // 显示所有书籍
    void showBooks() {
        for (int i = 0; i < bookCount; i++) {
            cout << "书名:" << books[i]->getTitle() << endl;
            cout << "作者:" << books[i]->getAuthor() << endl;
            cout << "出版社:" << books[i]->getPublisher() << endl;
            cout << "出版日期:" << books[i]->getPublishDate() << endl;
            cout << "---------------------" << endl;
        }
    }
};
 
// 主函数
int main() {
    Library library; // 创建图书馆对象
 
    // 添加一些书籍
    Book* book1 = new Book("《三国演义》", "罗贯中", "人民文学出版社", "1973 年");
    Book* book2 = new Book("《红楼梦》", "曹雪芹", "中华书局", "1982 年");
    Book* book3 = new Book("《西游记》", "吴承恩", "上海古籍出版社", "1995 年");
 
    library.addBook(book1);
    library.addBook(book2);
    library.addBook(book3);
 
    // 显示所有书籍
    library.showBooks();
 
    // 删除一本书
    library.removeBook("《红楼梦》");
 
    // 显示所有书籍
    library.showBooks();
 
    // 查找一本书
    Book* foundBook = library.findBook("《三国演义》");
    if (foundBook!= NULL) {
        cout << "找到书籍:" << foundBook->getTitle() << endl;
    } else {
        cout << "未找到书籍" << endl;
    }
 
    return 0;
}
  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-28 12:31
    关注

    引自免费微信小程序:皆我百晓生

    在C++中,Book* findBook(string title) 函数返回类型为 Book* 是因为它可能返回一个指向 Book 对象的指针。当我们在库中查找一本书时,可能会找到这本书(在这种情况下,函数将返回一个指向该书的指针),也可能找不到(在这种情况下,函数会返回 NULL 或者现代C++中的 nullptr)。使用指针是因为可以灵活处理这两种情况,而且在C++中,对象通常不会被复制而是被移动或共享,这样可以节省内存资源。

    至于删除书籍和添加书籍函数,它们实际上是 Library 类的成员函数,因为它们在 Library 类的 public 部分进行了声明。虽然在函数定义中没有明确写出 Library 类的前缀,但是编译器可以根据它们所在的文件和上下文推断出它们属于哪个类。这是因为这些函数是在类的内部定义的,所以它们具有隐式的访问权限,可以直接访问类的私有和保护成员。在函数签名中不需要显式指定 this 指针,因为在成员函数内部,this 指针自动指向当前对象实例。

    下面是修改过的代码,我添加了注释以便更好地解释:

    #include <iostream>
    using namespace std;
    
    // Book 类定义
    class Book {
    private:
        string title;
        string author;
        string publisher;
        string publishDate;
    
    public:
        // 构造函数
        Book(string title, string author, string publisher, string publishDate)
            : title(title), author(author), publisher(publisher), publishDate(publishDate) {} // 初始化列表
    
        // 析构函数
        ~Book() {}
    
        // 获取书名
        string getTitle() const { return title; } // 添加const修饰符,表明此方法不会改变对象状态
    
        // 获取作者
        string getAuthor() const { return author; }
    
        // 获取出版社
        string getPublisher() const { return publisher; }
    
        // 获取出版日期
        string getPublishDate() const { return publishDate; }
    };
    
    // Library 类定义
    class Library {
    private:
        Book* books[100]; // 存储书籍的数组
        int bookCount;    // 书籍数量
    
    public:
        // 构造函数
        Library()
            : bookCount(0) {
            for (int i = 0; i < 100; i++) {
                books[i] = nullptr;
            }
        }
    
        // 析构函数
        ~Library() {
            for (int i = 0; i < bookCount; i++) {
                delete books[i];
            }
        }
    
        // 添加书籍
        void addBook(Book* book) {
            books[bookCount++] = book;
        }
    
        // 删除书籍
        void removeBook(string title) {
            for (int i = 0; i < bookCount; i++) {
                if (books[i]->getTitle() == title) {
                    delete books[i];
                    for (int j = i; j < bookCount - 1; j++) {
                        books[j] = books[j + 1];
                    }
                    bookCount--;
                    break;
                }
            }
        }
    
        // 查找书籍
        Book* findBook(string title) {
            for (int i = 0; i < bookCount; i++) {
                if (books[i]->getTitle() == title) {
                    return books[i];
                }
            }
            return nullptr; // 使用nullptr代替NULL
        }
    
        // 显示所有书籍
        void showBooks() {
            for (int i = 0; i < bookCount; i++) {
                cout << "书名:" << books[i]->getTitle() << endl;
                cout << "作者:" << books[i]->getAuthor() << endl;
                cout << "出版社:" << books[i]->getPublisher() << endl;
                cout << "出版日期:" << books[i]->getPublishDate() << endl;
                cout << "---------------------" << endl;
            }
        }
    };
    
    // 主函数
    int main() {
        Library library; // 创建图书馆对象
    
        // 添加一些书籍
        Book* book1 = new Book("《三国演义》", "罗贯中", "人民文学出版社", "1973 年");
        Book* book2 = new Book("《红楼梦》", "曹雪芹", "中华书局", "1982 年");
        Book* book3 = new Book("《西游记》", "吴承恩", "上海古籍出版社", "1995 年");
    
        library.addBook(book1);
        library.addBook(book2);
        library.addBook(book3);
    
        // 显示所有书籍
        library.showBooks();
    
        // 删除一本书
        library.removeBook("《红楼梦》");
    
        // 显示所有书籍
        library.showBooks();
    
        // 查找一本书
        Book* foundBook = library.findBook("《三国演义》");
        if (foundBook != nullptr) {
            cout << "找到书籍:" << foundBook->getTitle() << endl;
        } else {
            cout << "未找到书籍" << endl;
        }
    
        return 0;
    }
    

    这段代码已经包含了我对问题的解答和一些改进,例如添加了初始化列表,将某些方法标记为常量成员函数(const),并使用 nullptr 替换 NULL

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 5月6日
  • 已采纳回答 4月28日
  • 创建了问题 4月28日

悬赏问题

  • ¥15 麒麟V10桌面版SP1如何配置bonding
  • ¥15 Marscode IDE 如何预览新建的 HTML 文件
  • ¥15 K8S部署二进制集群过程中calico一直报错
  • ¥15 java python或者任何一种编程语言复刻一个网页
  • ¥20 如何通过代码传输视频到亚马逊平台
  • ¥15 php查询mysql数据库并显示至下拉列表中
  • ¥15 freertos下使用外部中断失效
  • ¥15 输入的char字符转为int类型,不是对应的ascall码,如何才能使之转换为对应ascall码?或者使输入的char字符可以正常与其他字符比较?
  • ¥15 devserver配置完 启动服务 无法访问static上的资源
  • ¥15 解决websocket跟c#客户端通信