【发布时间】:2020-09-23 03:37:43
【问题描述】:
首先,我是 C++ 新手,我正在努力学习它。也是stackoverflow的新手。 很难说实话。 如果您对我的代码以及如何改进它有更多的 cmets,请告诉我,因为我仍在学习过程中。
好吧,我只是使用面向对象编程创建了一个在线预订系统。
好的,主要问题是我不明白为什么 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;
}
【问题讨论】:
-
不相关(这里也无所谓):不管成员初始化器列表中使用的顺序如何,成员变量都按照它们定义的顺序进行初始化。
genre在Book中首先初始化,即使它在列表中是最后一个。Book中的成员之间没有相互依赖关系,但是当存在时,请注意! -
auto lib=system.getLibrary();是 100% 的值语义。Library按值返回并按值存储,因此lib.addBook("Adventure of Pablo",1234,BookGenre::Adventure);对副本进行操作。恐怕你需要更早地开始测试你的代码。 -
@user4581301 是的,这最终成为了根本问题(但使用
manager而不是lib)。顺便说一下,关于初始化顺序的好提示;我不知道。再说一遍.. 有一段时间没做过 C++ 了 :) -
非常感谢,我现在很高兴,我感到很沮丧,但是是的,我会遵循所有的提示!
-
我能给的最大建议是获得一个带有良好调试器的 IDE。使用调试器,您可以单步执行程序并逐行检查它的功能(使用好的调试器,您可以做的远不止这些)。一旦你发现程序做了一些你没有预料到的事情,通常是走错了路径或存储了错误的值,你就发现了一个错误。了解和修复错误需要做更多工作,但发现它是一个重要的早期步骤。
标签: c++ smart-pointers object-oriented-analysis