Object-Oriented Programming-pure virtual functions, containers and inheritance
I.Pure virtual functions
Write = 0 next to the function parameter to specify the pure virtual function:
Class Disc_item: public Item_base {public: double net_price (size_t) const = 0; // specify the pure virtual function };
Defining a function as a pure virtual function can explain that this function provides an interface that can be overwritten by the descendant type, but the version of this class will never be called. Importantly, you cannot create Disc_item objects.
Disc_item discount; // Error Bulk_item bulk; // OK // because the Bulk_item class inherits from the Disc_item class, And the net_price function is rewritten.
[Note]
Contains (or inherits) one or morePure virtual functionsThe class isAbstract base class. ExceptObject components of a derived classYou cannot create abstract objects.
// P503 exercise 15.26/27 class Disc_item: public Item_base {public: Disc_item (const std: string & book = "", double sales_price = 0.0, std :: size_t qty = 0, double disc_rate = 0.0): Item_base (book, sales_price), quantity (qty), discount (disc_rate) {} double net_price (size_t) const = 0; protected: std: size_t quantity; double discount;}; // ...int main () {Disc_item ;}
Error message:
II.Container and inheritance
We want to use containers (or built-in arrays) to save objects associated with inheritance. However, objects are not polymorphism. This fact affects the use of containers in the inheritance hierarchy.
If you define multiset to save objects of the base class type:
Multiset
Basket; Item_base base; Bulk_item bulk; basket. insert (base); // OK basket. insert (bulk); // OK: However, the part of the bulk derived class will be ruthlessly cut out.
When an object of the derived type is added, only the base class of the object is saved in the container. Remember: When copying a derived class object to a base class object, the derived class object will be cut out. Therefore, once a multi-dataset is put in, it is no longer a derived class object.
[Careful mine]
Because a derived class object is "dropped" when assigned to a base class object, the container and the types related to inheritance cannot be well integrated.
This problem cannot be solved by defining the container to save the derived class object. In this case, the Item_base object cannot be put into the container -- there is no standard conversion from the base class type to the derived type. You can explicitly convert a base class object to a derived class object and add the result object to the container. However, if you try to use such an element,Big problems: In this case, elements can be treated as derived class objects, but some members of the derived class are not initialized.
The only viable option may be to use containers.Save object pointer. This policy is feasible, but the cost isUsers need to manage objects and pointers,You must ensure that the object to be directed exists as long as the container exists. If the object is dynamically allocated, you must ensure that the object is released properly when the container disappears.
// P504 exercise 15.28int main () {vector
ItemVec; for (size_t I = 0; I! = 10; ++ I) {Bulk_item item ("C ++ Primer", 6, 5, 0.5); itemVec. push_back (item);} double sum = 0; for (vector
: Iterator iter = itemVec. begin (); iter! = ItemVec. end (); ++ iter) {sum + = iter-> net_price (10); // call Item_base: net_price} cout <sum <endl; // output 600}
// Exercise 15.29int main () {vector
ItemVec; for (size_t I = 0; I! = 10; ++ I) {Bulk_item * item = new Bulk_item ("C ++ Primer", 0.5,); itemVec. push_back (item);} double sum = 0; for (vector
: Iterator iter = itemVec. begin (); iter! = ItemVec. end (); ++ iter) {sum + = (* iter)-> net_price (10);} cout <sum <endl; // output 300 // explicitly releases the dynamically allocated memory for (vector
: Iterator iter = itemVec. begin (); iter! = ItemVec. end (); ++ iter) {delete * iter ;}}