My code is fine, but there is an outstanding exception.
#include <iostream>
using namespace std;
class Book {
public:
string title;
string ISBN;
double price;
Book(string title_B, string ISBN_B, double price_B ) : title{title_B}, ISBN{ISBN_B}, price{price_B} {}
void ShowBookInfo() {
cout << "Title: " << title << endl;
cout << "ISBN: " << ISBN << endl;
cout << "Price(USD): " << price << endl;
}
};
class EBook : public Book {
public:
string DRMKey;
string format;
EBook(string title_B, string ISBN_B, double price_B, string DRMKey_B, const string& format_B = "Kindle") : Book{ title , ISBN , price }, DRMKey{ DRMKey_B }, format{ format_B } {}
void ShowEBookInfo() {
cout << "Title: " << title << endl;
cout << "ISBN: " << ISBN << endl;
cout << "Price(USD): " << price << endl;
cout << "DRMKey: " << DRMKey << endl;
cout << "Format: " << format << endl;
}
};
int main() {
Book book("Modern C Programming Cookbook", "1800208987", 49.99);
book.ShowBookInfo();
cout << endl;
EBook ebook("Modern C Programming Cookbook(ebook)", "1800208987", 34.99, "dkb34x!@*~");
ebook.ShowEBookInfo();
return 0;
}
When the F10 shortcut key is used to execute code line by line. An error occurs when an unprocessed exception occurs in the "EBookbook(~~);" position. What's the problem?
Output
Title: Modern C Programming Cookbook
ISBN: 1800208987
Price(USD): 49.99
Expected
Title: Modern C Programming Cookbook
ISBN: 1800208987
Price(USD): 49.99
Title: Modern C Programming Cookbook(ebook)
ISBN: 1800208987
Price(USD): 34.99
DRMKey: dkb34x!@*~
Format: Kindle
CodePudding user response:
When you call the constructor of "EBook", you first try to initialize your base class "Book". That is correct.
But you try to initialize it with its own, not yet initialized members "title", "ISBN" and "price". The value of those "Book"-class data members is a this time not yet determined. The values are undetermined.
And then the assignment will not work. In your case, the system tries to allocate too much memory and then you get an exception in the "new" operator or in the std::basic_string
constructor, when it tries to "construct" the string data with the uninitialized value. But, it can happen everywhere, because, as said, we have undefined behavior here.
The fix is simple: Use the correct variables from your "EBook" constructor to initialize the parent class' data members.
The whole updated code would then look like this
#include <iostream>
#include <string>
using namespace std::string_literals;
class Book {
public:
Book() {};
std::string title{};
std::string ISBN{};
double price{};
Book(const std::string& title_B, const std::string& ISBN_B, const double price_B) : title{ title_B }, ISBN{ ISBN_B }, price{ price_B } {}
void ShowBookInfo() const {
std::cout << "Title: " << title << "\nISBN: " << ISBN << "\nPrice(USD): " << price << '\n';
}
};
class EBook : public Book {
public:
std::string DRMKey{};
std::string format{};
EBook() : Book() {};
EBook(const std::string& title_B, const std::string& ISBN_B, const double price_B, const std::string& DRMKey_B, const std::string& format_B = "Kindle"s) : Book{ title_B , ISBN_B , price_B }, DRMKey{ DRMKey_B }, format{ format_B } {}
void ShowEBookInfo() const {
ShowBookInfo();
std::cout << "DRMKey: " << DRMKey << "\nFormat: " << format << '\n';
}
};
int main() {
Book book("Modern C Programming Cookbook", "1800208987", 49.99);
book.ShowBookInfo();
std::cout << '\n';
EBook ebook("Modern C Programming Cookbook(ebook)", "1800208987", 34.99, "dkb34x!@*~");
ebook.ShowEBookInfo();
}
CodePudding user response:
When you call the Book
base ctor:
Book{ title , ISBN , price }
You use the uninitialized yet base data members title
, ISBN
etc., instead of the arguments: title_B
, ISBN_B
etc.
Therefore you should change the base ctor call to:
Book{ title_B , ISBN_B , price_B }
Also for efficiency (avoid a copy), you can accept the std::string
s by const &
instead of by value:
//-----------vvvvvvv-----------------vvvvvvv-------------------------------vvvvvvvv
EBook(string const & title_B, string const & ISBN_B, double price_B, string const & DRMKey_B, const string& format_B = "Kindle") : //...
A side note: better to avoid using namespace std
- see here Why is "using namespace std;" considered bad practice?.