我正在编写一个程序,您可以在其中插入和显示一些书籍(不使用数据库)。
为此,我使用三个类:
Book -是基类。TehnicBook和Literature --这将继承Book的一些属性。#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
class Book {
public:
string author, title;
bool rented;
Book(string &author, string &title, bool rented) {
this -> author = author;
this -> title = title;
this -> rented = rented;
};
void display(void);
};
class TehnicBook:public Book {
int amount, RlYear;
string language;
TehnicBook *head, *next;
public:
TehnicBook(string &author, string &title, bool rented, int amount, string &language, int RlYear):Book(author, title, rented) {
head = NULL;
this -> language = language;
this -> amount = amount;
this -> RlYear = RlYear;
};
~TehnicBook(void) {
delete head;
};
void display(void);
void add(void);
void dellete(string&);
};
class Literature:public Book {
string bookType;
Literature *head, *next;
public:
Literature(string &author, string &title, bool rented, string &bookType):Book(author, title, rented) {
head = NULL;
this -> bookType = bookType;
};
~Literature(void) {
delete head;
};
void display(void);
void add(void);
};
void TehnicBook::add(void) {
string author, title, language;
int year, amount;
bool rented;
cout << endl << "Author: ", cin >> author;
cout << "Title: ", cin >> title;
cout << "Rented? (0/1): ", cin >> rented;
cout << "The amount of books: ", cin >> amount;
cout << "Language: ", cin >> language;
cout << "Release year: ", cin >> year;
TehnicBook *p = new TehnicBook(author, title, rented, amount, language, year);
p -> next = head;
head = p;
}
void TehnicBook::display(void) {
TehnicBook *p = head;
while(p) {
cout << "-----------------------------\n";
cout << "Author: " << p -> author << endl;
cout << "Title: " << p -> title << endl;
cout << "Is " << ((p -> rented) ? "" : "not ") << "rented" << endl;
cout << "Amount of books: " << p -> amount << endl;
cout << "Language: " << p -> language << endl;
cout << "Release year: " << p -> RlYear << endl;
cout << endl;
p = p -> next;
}
}
void Literature::add(void) {
string author, title, bookType;
bool rented;
cout << "\nAuthor: ", cin >> author;
cout << "Title: ", cin >> title;
cout << "Is rented? ", cin >> rented;
cout << "Book type (hardcover/...: ", cin >> bookType;
Literature *p = new Literature(author, title, rented, bookType);
p -> next = head;
head = p;
}
void Literature::display(void) {
Literature *p = head;
while(p) {
cout << "\n-----------------------------\n";
cout << "Author: " << p -> author << endl;
cout << "Title: " << p -> title << endl;
cout << "Is rented? " << ((p -> rented) ? "yes" : "no") << endl;
cout << "Book type: " << p -> bookType << endl << endl;
p = p -> next;
}
}
int main(int argc, char const **argv) {
string blank = "";
TehnicBook *tehnicB = new TehnicBook(blank, blank, false, 0, blank, 0);
Literature *litB = new Literature(blank, blank, false, blank);
int opt;
for(;;) {
cout << "\n\n1) Add a tehnic book.\n";
cout << "2) Display all tehnic books.\n";
cout << "3) Add a literature book.\n";
cout << "4) Display all literature books.\n";
cout << "5) Exit.\n\n";
cout << "Your option: ", cin >> opt;
switch(opt) {
case 1:
tehnicB -> add();
break;
case 2:
tehnicB -> display();
break;
case 3:
litB -> add();
break;
case 4:
litB -> display();
break;
case 5:
exit(0);
default:
continue;
}
}
return 0;
}我做得对吗?有更好的主意吗?
发布于 2014-10-28 21:33:54
Book::~Book不是virtual。这意味着在以下情况下存在内存泄漏: TehnicBook *tb =新TehnicBook(.);tb->add(.);Book *b = tb;delete tb;//<- tb->head如果有C++11,建议每个类都有一个virtual析构函数,或者声明为final (如class Book final{...} )。TehnicBook与链接列表结合起来。一个类应该只有一个责任:要么管理一本书,要么管理内存,而不是两者兼而有之。至少使用std::list或更好的std::vector。最好将add从TehnicBook和Literature中删除,并将vector<Book>放入main以分离存储和功能。add不应该使用cin和cout。您正在混合用户界面和类功能。它应该只需要一个TehnicBook *。您可以创建一个可以方便地执行此操作的独立函数,但它不应该是TehnicBook的一部分。display不应该使用cout。让它返回一个string,然后交给cout,或者教cout如何打印这样的书: ostream &operator <<(ostream & os,TehnicBook &t){ os << os <<“?”?“os <<”是“<< ((p->租赁物)?”:"not“<<租来的”<< endl;os <<“图书数量:”<< p-> << << endl;os << "Language:“<< p->language << endl;os <<”发行年:“<< p->RlYear << endl;os << endl;year os;}现在您可以做TehnicBook book(...); cout << book;了,这很不错,但是更重要的是,您可以做一些像ofstream file("test.txt"); file << book;这样的事情,所以我们可以免费将一本书打印到文件和TCP流等等。void dellete(string&);在TehnicBook中,但没有实现。我想您是想添加从列表中删除书籍的功能。删除此函数,它不属于TehnicBook。TehnicBook应该是TechnicBook还是TechnicalBook?new和delete。永远不会。相反,请使用make_unique。TehnicBook *tehnicB =新的TehnicBook(空白,空白,假,0,空白,0);变成自动tehnicB =make_unique(空白,空白,假,0,空白,0);重点是现在不需要管理内存。管理内存非常困难,而且容易出错,而且没有必要。例如,您忘记清理tehnicB和litB中的main。这会自动修复,而不用考虑使用现代C++。发布于 2014-10-28 20:04:04
Bug:您不能为任何字符串参数输入多个单词,例如作者和标题。在这里阅读整行将更有意义,例如:
cout << endl << "Author: ";
getline(cin, author);请不要使用using namespace std (阅读这)。不过,这是可以的:
using std::cin;
using std::cout;
using std::endl;
using std::string;但是最好不要这样做,而是在需要时显式使用std::cout,特别是对于像string这样的常见名称,这很容易与其他实现发生冲突。另见@Loki的评论。
而不是#include <stdlib.h>,而是这样写:#include <cstdlib>。但实际上,正如@Edward所指出的,最好删除此导入,并将单个exit(0)语句更改为return 0。
在->周围放置空格是不寻常的。更常见的情况是:
this->author = author;RlYear不是一个很好的名字。通常对变量名使用camelCase。对于这个变量,releaseYear将是一个更好的名称。
您可以将Book的构造函数简化如下:
Book(string &author, string &title, bool rented) :
author(author), title(title), rented(rented) {}类似地,这样的TechnicBook:
TehnicBook(string &author, string &title, bool rented, int amount, string &language, int RlYear) :
Book(author, title, rented), head(NULL), language(language), amount(amount), RlYear(RlYear) {}最后,虽然标题上写着"c++多态性“,但是在这段代码中没有多态性的例子。
https://codereview.stackexchange.com/questions/68219
复制相似问题