Do not redefine the inherited default parameter values

Source: Internet
Author: User
Tags types of functions

 

 
Do not redefine the inherited default parameter values

 

Let's simplify the problem from the very beginning. Default parameters can only exist as part of a function. In addition, only two types of functions can be inherited: virtual functions and non-virtual functions. Therefore, the only way to redefine the default parameter value is to redefine an inherited function. However, redefining the inherited non-virtual functions is an error (see section 37). Therefore, we can narrow down the scope of the discussion to "inherit a virtual function with default parameter values.

In this case, the reasons for these terms become very obvious: virtual functions are dynamically bound, while default parameter values are statically bound.

What does it mean? You may say that you do not understand these latest object-oriented terms; or, if you are overtired, you cannot remember the differences between static and dynamic binding. So, let's review it.

The static type of the object refers to the type that you declare that exists in the program code text. See the following class hierarchy:

Enum shapecolor {red, green, blue };

// A class that represents the geometric shape
Class shape {
Public:
// All shapes must provide a function to draw them themselves
Virtual void draw (shapecolor color = Red) const = 0;

...

};

Class rectangle: Public shape {
Public:
// Note: different default parameter values are defined. ---- Not good!
Virtual void draw (shapecolor color = green) const;

...

};

Class circle: Public shape {
Public:
Virtual void draw (shapecolor color) const;

...

};

It is shown in the figure below:

Shape
//
//
//
Rectangle circle

Now let's look at these pointers:

Shape * pS; // static type = shape *

Shape * Pc = new circle; // static type = shape *

Shape * Pr = new rectangle; // static type = shape *

In this example, PS, PC, and PR are declared as shape pointer types, so they all use them as their own static types. Note that this is absolutely irrelevant to the type of the objects they actually point to-their static types are always shape *.

The dynamic type of an object is determined by the type of the object it currently refers. That is, the dynamic type of the object indicates the behavior it will perform. In the above example, the dynamic type of PC is circle *, and the dynamic type of PR is rectangle *. As for PS, there is actually no dynamic type, because it (not yet) does not point to any object.

The dynamic type, as the name implies, can be changed when the program is running. A typical method is to assign values:

PS = pc; // The dynamic type of PS
// It is circle *

PS = Pr; // The dynamic type of PS
// Rectangle *

Virtual functions are dynamically bound, meaning that the dynamic type of the called function depends on the object through which the virtual function is called:

PC-> draw (red); // call circle: Draw (red)

Pr-> draw (red); // call rectangle: Draw (red)

I know that these are all old-fashioned knowledge, and you certainly know virtual functions. (If you want to know how they are implemented, refer to the M24 clause.) However, if you combine virtual functions with default parameter values for analysis, the problem arises, because, as described above, virtual functions are dynamically bound, but default parameters are statically bound. This means that you may eventually call a virtual function that is defined in the derived class but uses the default parameter value in the base class:

Pr-> draw (); // call rectangle: Draw (red )!

In this case, the dynamic type of PR is rectangle *, so the virtual function of rectangle is called-as we expected. In rectangle: draw, the default value is green. However, since the PR static type is shape *, the parameter value called by this function is obtained from the shape class, rather than the rectangle class! So the results will be very strange and unexpected, because this call contains a combination of the draw declarations in the shape and rectangle classes. Of course you don't want your software to run in this way; at least, you don't want it, believe me.

Needless to say, the fact that PS, PC, and PR are pointers has nothing to do with the cause of the problem. If they are references, the problem persists. The problem is that draw is a virtual function and its default parameter is redefined in the subclass.

Why does C ++ stick to this unconventional approach? The answer is related to the running efficiency. If the default parameter value is dynamically bound, the compiler must find a proper default value for the virtual function at runtime, this is more complex than the mechanism used to determine the default value in the compilation phase. This kind of choice is intended to improve the speed and simplify the implementation, So now everyone can feel the efficiency of running the program. Of course, if you ignore the suggestions in these terms, it will bring chaos.

 

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.