Effective C ++ 2e Item37

zhaozj2021-02-11  191

Terms 37: Never redefine the inherited non-virtual functions

There are two ways to look at this problem: the methods and practices of theory. Let us start with practical methods. After all, theologists are generally patient.

Assume that class D is inherited in class B, and a public member function MF is defined in class B. The parameters and return types of the MF are not important, so it is assumed to be VOID. In other words, I write this:

Class B {public: void mf (); ...};

Class D: public b {...};

Even without knowing B, D or MF, you can define a type D object X,

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

So, if you find this:

B * Pb = & x; // Get x pointer

Pb-> mf (); // call MF through the pointer

And doing the execution behavior below is different:

D * pd = & x; // Get x pointer

PD-> mf (); // call MF through the pointer

You will be very surprised.

Because in both cases, all the member functions MF of object X, because in both cases, the same function and the same object, the behavior will be the same, right?

Yes, it will be the same. However, it may not be the same. In particular, if the MF is a non-virtual function and D has defined its own MF version, the behavior will not be the same:

Class D: public b {public: void mf (); // Hide B :: MF; see Terms 50

...

}

PB-> mf (); // Call B :: MF

PD-> mf (); // Call D :: MF

The reason for the two-sided behavior is that the non-virtual functions such as B :: MF and D :: MF are static bindings (see Terms 38). This means that because the PB is declared to point to B's pointer type, it will always call the functions defined in class B when calling the non-virtual function through the Pb ---- Even if PB points to the object from b-derived class As shown in the above example.

Instead, the virtual function is dynamically binding (see Terms 38 again), so this type of problem will not occur. If the MF is a virtual function, it will cause call D :: MF when the MF is called by the PB or PD, because the PB and PD actually points to the object of type D.

Therefore, the conclusion is that if the write class D redefines the object of non-virtual functions MF, D from class B, may show abnormal behavior of schizophrenia. That is, when the object of D is called in the MF, the behavior may be like B, and it is also possible like D, the determination factor, and the object itself have no relationship, but depends on the type declared by the pointer to its pointer. The reference will also show such an abnormal behavior as the pointer.

The arguments in practice are so much. I know what you want to know now, what is the theoretical basis for redefining the inherited non-virtual functions. I am very happy to answer.

Terms 35 explain the meaning of public inheritance is "Yes", and the clause 36 explains why "declare a non-virtual function in a class actually establishes a particularity of particularity for this class." If you use these analysis to class B, class D and non-virtual member functions b :: mf, then,

· Everything for the B object is also suitable for D object because the object "is a" object of each D. · The subclass of B must inherit the interface and implementation of the MF at the same time, as the MF is a non-virtual function in B. Then, if D is redefined with MF, there is a contradiction in the design. If D really needs to achieve different MF, and each B object ---- no matter how special ---- really want to use B-implemented MF, then each D will not be "one" B. In this case, D cannot be inherited from B. Conversely, if D really must inherit from B, and D really requires different MF implementations, then MF does not reflect the non-variability of specificity. In this case, the MF should be a virtual function. Finally, if each D is really "is a" B, and if the MF is really non-variability, then D actually does not need to redefine the MF, it will never do this.

Regardless of which of the above arguments can be drawn: Under any conditions, the non-virtual function of redefining inheritance is prohibited.

转载请注明原文地址:https://www.9cbs.com/read-4449.html

New Post(0)