Reading Notes Objective c ++ Item 36 never redefines the inherited non-virtual functions.

Source: Internet
Author: User

Reading Notes Objective c ++ Item 36 never redefines the inherited non-virtual functions.
1. Why not redefine the inherited non-virtual functions-actual arguments

Suppose I tell you a Class D public inherits Class B and defines a public member function mf in Class B. Mf parameters and return types are not important, so assume they are all void. The implementation is as follows:

1 class B {2 public:3 void mf();4 ...5 };6 lass D: public B { ... }

We do not need to know any details about B, D, or mf. Consider an object x of the type D,

1 D x;                               // x is an object of type D

You will be surprised if the following statement:

1 B *pB = &x;                               // get pointer to x2 3 pB->mf();                                 // call mf through pointer

 

Different from the following statement

1 D *pD = &x;                              // get pointer to x2 3 pD->mf();                                // call mf through pointer

 

In both cases, you trigger the member function mf of object x. Because the two cases use the same object and the same function, the behavior should be the same, isn't it?

This should be the case. But it may not. In particular, if mf is a non-virtual function and D defines its own mf version, the above behavior will be different:

 1 class D: public B { 2 public: 3 void mf();         // hides B::mf; see Item 33 4  5 ...                      6  7 }; 8 pB->mf();         // calls B::mf 9 10 pD->mf();         // calls D::mf

 

The reason for this two-sided behavior is that non-virtual functions such as B: mf and D: mf are statically bound (statically bound Item37 ). This means that because pB is declared as a pointer to B, all non-virtual functions triggered by pB are defined on Class B, even if pB points to the derived class object of B, that is, the implementation in this example.

Virtual functions are dynamically bound (dynamically boundItem 37), so they do not have the above problems. If mf is a virtual function, calling mf through pB or pD triggers D: mf, because pB or pD actually points to the object of Type D.

If you implement a Class D and redefine the non-virtual function mf inherited from Class B, the D object will also exhibit inconsistent behavior. In particular, the act of calling the mf function through the D object may be like B or D, and the object itself is not a deciding factor. The deciding factor is the pointer type pointing to the D object. The behavior shown by the reference is the same as that of the pointer.

2. Why not redefine the inherited non-virtual functions-Theoretical Arguments

 

The above is only a practical demonstration. I know what you really want to know is the theoretical proof that "do not redefine the inherited non-virtual functions. See the following analysis:

Item 32 explains that pulibc inheritance means "is-", item34 describes why a non-virtual function is defined in a class as an immutable (invariant overspecialization ). If you apply these observations to Class B or Class D and non-virtual member function B: mf, you will find:

  • Everything applied to Class B can also be applied to Class D, because every D object is a Class B object.
  • Classes derived from Class B inherit both the interface and implementation of mf, because mf is a non-virtual function in Class B.

Now, if D re-Defines mf, there will be a conflict in your design. If D really wants to implement a mf different from B, and if every B object -- no matter how special -- must actually use B for mf, every D object is a B object. In this case, D should not inherit from B. In another aspect, if D must be public inherited from B, and D must implement a mf different from B, then, the extra immutability of mf for B is no longer true. In this case, mf should be virtual. Finally, if every D is actually a B, and if mf is actually a special immutability for B, then D really does not need to be redefined, you shouldn't try this either.

No matter which point of view or conclusion is the same, it is prohibited to redefine an inherited non-virtual function.

3. You should be familiar with the terms.

If you read this clause, it may be because you have read Item7. This clause explains why the virtual function in the polymorphism base class should be virtual. If you violate the terms in Item7 (that is, you declare a non-virtual destructor in the polymorphism base class), you will also violate the terms, because the derived class will always redefine the inherited non-virtual function: The destructor of the base class. This is true for a derived class without a defined destructor, because, as explained in Item 5, if you do not declare the Destructor yourself, the compiler will automatically generate one for you. In essence, Item7 is only a special case of this clause, although it is important enough to become a separate clause.

4. Summary
    • Never redefine an inherited non-virtual function.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.