Re-read
Item 36: Never redefine an inherited non-virtual function
If you are writing class D and you redefine a non-virtual function mf that you inherit from class B, D objects will likely exhibit inconsistent behavior. In particular, any given D object may act like either a B or a D when mf is called, and the determining factor will have nothing to do with the object itself, but with the declared type of the pointer that points to it. References exhibit the same baffling behavior as do pointers.
Item 37: Never redefine a function's inherited default parameter value
virtual functions are dynamically bound, but default parameter values are statically bound. static binding is also known as early binding, and dynamic binding is also known as late binding. That means you may end up invoking a virtual function defined in a derived class but using a default parameter value from a base class:
Item 38: Model "has-a" or "is-implemented-in-terms-of" through composition
Item 39: Use private inheritance judiciously
private inheritance doesn't mean is-a.
- in contrast to public inheritance, compilers will generally not convert a derived class object (such as Student) into a base class object (such as Person) if the inheritance relationship between the classes is private.
- members inherited from a private base class become private members of the derived class, even if they were protected or public in the base class.
Item 40: Use multiple inheritance judiciously
class BorrowableItem { // something a library lets you borrow
public: void checkOut(); // check the item out from the library ...
};
class ElectronicGadget {
private:
bool checkOut() const; // perform self-test, return whether
... // test succeeds
};
class MP3Player: // note MI here
public BorrowableItem, // (some libraries loan MP3 players)
public ElectronicGadget
{ ... }; // class definition is unimportant
MP3Player mp;
mp.checkOut(); // ambiguous! which checkOut?
mp.BorrowableItem::checkOut(); // this way
Not finish the late half part.
No comments:
Post a Comment