首先,我是 c++ 的新手,我正在努力学习它。也是 stackoverflow 的新手。 发现很难说实话。 如果您对我的代码以及我如何改进它有其他意见,请告诉我,因为我仍在学习过程中。
好吧,我只是使用面向对象编程创建了一个在线预订系统。
好吧,主要问题是我不明白为什么 system.setDisplay(1234); 没有打印任何东西。我已经尝试了一切,只是没有加起来。 OnlineBookingSystem 是用于调用 setDisplay(id) 然后调用显示类的类。 如果你能提供帮助,这对我来说意义重大,我得到的错误是:
运行时错误:成员调用“用户”类型的空指针 (solution.cpp) 摘要:UndefinedBehaviorSanitizer:undefined-behavior prog_joined.cpp:179:54
#include <vector>
#include <string>
#include <iostream>
#include <memory>
#include <queue>
using namespace std;
enum class BookGenre
{
Horror,Adventure,Romance,Comic
};
class Book
{
private:
BookGenre genre;
string title;
size_t id;
public:
Book(string title,size_t id,BookGenre genre):title(title),id(id),genre(genre){}
string getTitle(){return title;}
size_t getId(){return id;}
BookGenre getGenre(){return genre; }
};
class Library
{
private:
vector<shared_ptr<Book>> listOfBooks;
public:
Library(){};
void addBook(string title,size_t id,BookGenre genre)
{
listOfBooks.push_back(make_shared<Book>(title,id,genre));
}
shared_ptr<Book> getBook(size_t id)
{
for(auto&x:listOfBooks)
{
if(x->getId()==id)
{
return x;
}
}
return nullptr;
}
void removeBook(size_t id)
{
for(auto it=listOfBooks.begin();it!=listOfBooks.end();it++)
{
if((*it)->getId()==id)
{
listOfBooks.erase(it);
}
}
}
};
class User
{
protected:
size_t id;
string username;
public:
User(size_t id,string username):id(id),username(username)
{
}
virtual ~User(){}
size_t getId(){return id;}
string getUsername(){return username;}
};
class Employee:public User{
private:
double salary;
public:
Employee(size_t id,string username,double salary):User(id,username),salary(salary)
{
}
void setSalary(double salary)
{
this->salary=salary;
}
double getSalary(){return salary;}
};
class Customer:public User{
private:
bool membership;
public:
Customer(size_t id,string username):User(id,username)
{
membership=false;
}
void setMemberActive()
{
membership=true;
}
bool isMemberActive()
{
return membership;
}
};
class UserManager
{
private:
vector<shared_ptr<User>>listOfUsers;
queue<shared_ptr<Customer>>queue;
public:
UserManager()
{
}
void addCustomer(size_t id,string username)
{
listOfUsers.push_back(make_shared<Customer>(id,username));
}
void removeCustomer(string username)
{
for(auto it=listOfUsers.begin();it!=listOfUsers.end();it++)
{
if(dynamic_pointer_cast<Customer>(*it))
{
if((*it)->getUsername()==username)
{
listOfUsers.erase(it);
}
}
}
}
shared_ptr<Customer> getCustomer(string username)
{
for(auto it=listOfUsers.begin();it!=listOfUsers.end();it++)
{
if(dynamic_pointer_cast<Customer>(*it))
{
if((*it)->getUsername()==username)
{
return dynamic_pointer_cast<Customer>(*it);
}
}
}
return nullptr;
}
void addToQueue(string username)
{
queue.push(getCustomer(username));
}
void removeCurrentCustomer()
{
queue.pop();
}
shared_ptr<Customer> getNextCustomer()
{
if(queue.empty())
{
return nullptr;
}
return queue.front();
}
/*
same process for user;
*/
};
class Display
{
private:
shared_ptr<Customer> m_customer;
shared_ptr<Book> m_book;
public:
Display(shared_ptr<Customer> _customer,shared_ptr<Book> _book ):m_customer(_customer),m_book(_book)
{
}
shared_ptr<Customer> getUser(){return m_customer;}
shared_ptr<Book> getBook(){return m_book;}
void displayInfo()
{
cout<<"Customer username: "<<m_customer->getUsername()<<endl;
cout<<"Member Active: "<<m_customer->isMemberActive();
cout<<"book id: "<<m_book->getId()<<endl;
cout<<"book title: "<< m_book->getTitle()<<endl;
}
};
class OnlineBookingSystem
{
private:
UserManager manager;
Library library;
shared_ptr<Display>display;
public:
OnlineBookingSystem()
{
UserManager manager;
Library library;
this->manager=manager;
this->library=library;
this->display=nullptr;
}
Library getLibrary()
{
return library;
}
UserManager getUserManager()
{
return manager;
}
void setDisplay(size_t id)
{
display=make_shared<Display>( manager.getNextCustomer(),library.getBook(id));
display->displayInfo();
}
shared_ptr<Display> getDisplay()
{
return this->display;
}
};
int main()
{
OnlineBookingSystem system;
auto lib=system.getLibrary();
lib.addBook("Adventure of Pablo",1234,BookGenre::Adventure);
auto manager=system.getUserManager();
manager.addCustomer(2020,"Michael");
auto _customer= manager.getCustomer("Michael");
_customer->setMemberActive();
manager.addToQueue("Michael");
system.setDisplay(1234);
return 0;
}
最佳答案
我看到的问题:
问题1
由于 OnlineBookingSystem::getLibrary()
的返回类型是 Library
,因此行
auto lib=system.getLibrary();
将 lib
构造为 system
中对象的拷贝。对 lib
所做的任何更改都是对拷贝的更改,而不是对 system
中的 Library
对象的更改。
要解决此问题,请将返回类型更改为引用:
Library& getLibrary()
{
return library;
}
并捕获返回值也作为 main
中的引用。
auto& lib=system.getLibrary();
问题2
与问题 1 类似,但这次是在 OnlineBookingSystem::getUserManager
中。将其返回类型更改为引用:
UserManager& getUserManager()
{
return manager;
}
并捕获返回值也作为 main
中的引用。
auto& manager=system.getUserManager();
问题3
在每一步都采用防御性编程,直到出现性能瓶颈。如果一个函数的返回值可以是nullptr
,则在调用时检查返回值,当返回值确实是nullptr
时进行处理。
将 OnlineBookingSystem::setDisplay
更新为:
void setDisplay(size_t id)
{
display=make_shared<Display>( manager.getNextCustomer(),library.getBook(id));
if ( display )
{
display->displayInfo();
}
else
{
// Deal with the nullptr case
std::cout << "Unable to find a book with id " << id << std::endl;
}
}
关于C++,运行时错误 : member call on null pointer of type,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64020681/