Chapter 15 object oriented programming of C++ Primer
Section 15.7 answers to constructor and copy control exercises
Exercise 15.24: what kind of virtual destructor is required? What operations must the virtual destructor perform?
[Topic setting ideas]
Familiar with virtual destructors.
[answer]
The class used as a base class should have a virtual destructor to ensure that when deleting the base class pointer pointing to the dynamically allocated object, the appropriate destructor is run according to the type of the object actually pointed to by the pointer. The virtual destructor can be empty, that is, it does not perform any operation. Generally speaking, the main function of the destructor is to clear the data members defined in this class. If the class does not define a pointer class member, the composite version can be used; If the class defines a pointer member, you generally need to customize the destructor to properly clear the pointer member. Therefore, if there is an operation that the virtual destructor must perform, it is the operation of clearing the data members defined in this class.
Exercise 15.25: Why are we Disc_quote define a default constructor? If the constructor is removed, the bulk_ What impact does quote's behavior have?
[Topic setting ideas]
Understand the knowledge of synthetic copy control of base or derived classes.
[answer]
Because Disc_quote's default constructor will run quote's default constructor, and quote's default constructor will complete member initialization.
If you remove the constructor, Bulk_quote's default constructor cannot complete disc_ The initialization of quote.
Exercise 15.26: defining Quote and bulk_ The copy control member of Quote to make it consistent with the behavior of the synthesized version. Add print state statements for these members and other constructors so that we can know which program is running. Writing programs using these classes predicts which objects the program will create and destroy. Repeat the experiment and constantly compare whether your prediction and actual output are the same until the prediction is completely accurate.
[Topic setting ideas]
This question examines the calling process of constructor and destructor of base class and derived class.
[answer]
#include <iostream> #include <string> #include <ostream> using namespace std; class Quote { public: Quote() = default; Quote(const std::string &book = "", double sales_price = 0.0) :bookNo(book), price(sales_price) { cout << "Quote constructor is running===========" << endl; } string isbn() const { return bookNo; } //Returns the total sales amount of a given number of books. The derived class rewrites and uses different discount calculation methods virtual double net_price(std::size_t n) const { return n * price; } virtual void debug() { cout << "bookNo = " << bookNo << " price = " << price << endl; } virtual ~Quote() { cout << "Quote destructor is running=========" << endl; } friend ostream &operator << (ostream &, Quote &); private: std::string bookNo;//ISBN number of the book protected: double price = 0.0;//Represents the price without discount under normal conditions }; ostream& operator << (ostream &os, Quote &e) { os << "\tUsing operator << (ostram &, Quote &);" << endl; return os; } class Bulk_quote: public Quote { public: Bulk_quote(const string &book = "", double sales_price = 0.0, size_t qty = 0, double disc = 0.0) :Quote(book, sales_price), min_qty(qty), discount(disc) { cout << "Bulk_constructor is running" << endl; } ~Bulk_quote() { cout << "Bulk_quote destructor is running" << endl; } private: size_t min_qty; double discount; }; ostream &operator << (ostream &os, Bulk_quote &bq) { os << "\tUsing operator << (ostram &, Bulk_quote &)" << endl; return os; } int main(int argc, const char *argv[]) { Quote base("C++ Primer", 128.0); Bulk_quote bulk("Core Python Programming", 89, 5, 0.9); cout << base << endl; cout << bulk << endl; return 0; }
Operation results: