Some details in C + + classes (overloading, overriding, overwriting, hiding, constructors, destructors, copy constructors, assignment functions in the inheritance of some problems)

Source: Internet
Author: User
Tags class definition volatile

1 overloads of functions, overrides (redefinition), function overrides, and shadowing

In fact, function overloading and function rewriting, function overlay and function hiding are not a level concept. The former is the relationship between functions within the same class, or within the same function scope, with a different parameter list of the same name. The latter three are the relationships between the base class and the derived class function in different cases.

1.1 Function overloading

As mentioned above, the overloads of the functions refer to the relationships between the classes and the different parameter list functions of the same name. As follows:

void show();void show(int);void show(intdouble);

The above is a number of different functions with the same name parameter list, which is the function overloading. Different function return values are not used as the basis for judging function overloads, such as the following two functions will be judged as function redefinition.

void show();int show();

Compiler Error: "Error (Active) E0311 cannot overload functions that are differentiated only by return type."

However, the function overload should pay attention to the problem with the implicit conversion of the default parameters and types, and it is necessary to understand how the compiler chooses to use that version of the function. The general process is

    • The first step is to create a list of candidate functions. which contains the same function as the name of the called function
    • The second step is to create a list of possible functions using the list of candidate functions, which are all functions with the correct number of arguments, and for this there is an implicit conversion sequence, which includes the case where the real parameter type exactly matches the corresponding formal parameter type. For example, a function call that uses the float parameter can convert the argument to a double, which matches the double parameter.
    • The third step is to determine if there is the best possible function. If there is, use it, otherwise the function call is faulted (there is no match or there are multiple occurrences with errors)

So when you reload the function, be aware that there are default parameter values and implicit conversions, as follows:

 #include <iostream>  void  Show () {std::cout <<  "no parameters"  << Std::endl;} void  Show (int  n = 1 ) {std::cout << Span class= "St" and "parameters"  << Std::endl;} void  Show (double  d) {std::cout <<  << Std::endl;} void  Show (double  & D) {std::cout <<  << Std::endl;}   int  mian () {show ();  //e0308 has multiple overloaded functions "show" instances that match the parameter list:     double  d = 10 ;  Show (d); //e0308 has multiple overloaded function "show" instances matching the argument list }  

For cases with default parameter values, needless to say, for implicit conversions, be aware that the third-step compiler confirms that those are the best. It looks at the transformations needed to match the parameters of the function call to the arguments of the selected function when possible. Usually the order from best to worst is described below.

    1. Exact match
    2. Promote conversions (for example: Char automatically converts to int,float automatically converted to double)
    3. Standard conversions (for example: int to Char,long to double)
    4. User-defined conversions (e.g., transformation constructors for class definitions)

When an exact match is made, C + + allows some insignificant conversions, such as the following table:
| parameters |
|---|---|
| Type | Type & |
| Type & | Type |
| Type[] | Type * |
| Type (argument-list) | Type () (argument-list) |
| Type | Const Type |
| Type | Volatile Type |
| Type
| Const TYPE * |
| Type * | Volatile Type * |

1.2 Function overrides

This concept describes a function relationship between a base class and a derived class. Function overrides: The base class virtual function is redefined in the derived class. Such as:

class Base{  virtualvoid show()  {    ...  }}class BasePlus : pulic Base{  void show()  {    ...  }}

This form is the base class function with the virtual keyword, and the derived class is the same as the base class function name, and the argument list is the same. If the argument list is not the same, the function is hidden. This type is actually a derived class function that hides the base class function. In short, redefining a function in a derived class will not overwrite the base class declaration with the same function signature, but instead hides the base class method with the same name, regardless of the parameter signature. Therefore, if you redefine the inherited method, you should ensure that the original prototype is exactly the same, but if the return type is a base class reference or pointer, you can modify it to point to a reference or pointer to a derived class. If the base class declaration is overloaded, you should redefine all of the base class versions in the derived class. Because if you define only one version, the other two versions will be hidden and derived class objects will not be able to use them. If you do not need to modify it, you can only display the call base class method in the derived class definition function type.

1.3 Function hiding

Function hiding is divided into two cases, one is that the base class has the virtual keyword, but the list of parameters is different. The other is that there is no virtual keyword in the base class, but there is a function with the same name in the derived class (it doesn't matter if the argument list is different). At this point, if the derived class object calls the function, the function with the same name as the derived class is executed, and all the base class functions with the same name are hidden. At this point, a derived class cannot call any function of the same name as the base class. As follows:

class  base{: void  Show () {std::cout <<  << Std::endl; } void  Show (int  N) {std::cout <<  "Bas"    E: " << n << std::endl; }}; class         Baseplus:public  base{public : void  Show () {    Std::cout <<  "Baseplus is running!"  << Std::endl; }};    int  Main () {Baseplus ob;    Ob.show (); //ob.show (1); 1 error C2660: "Baseplus::show": function does not accept 1 parameters  system (); return  0 ;}  

If the base class object calls the function, it executes the base class function. A function that calls the base class if it is a base class reference or pointer to a derived class object.

1.4 Summary

In fact, to understand the dynamic binding of the class is not so troublesome, it is the base class object executes the base class function, the derived class object executes the derived class function. If the base class has the virtual keyword, then there is a pointer to the virtual function table in the base class, and if the derived class defines a function with the same name, the function pointer in the virtual function's label navigates to the function of the derived class. This is the phenomenon of function coverage. As for function hiding, it is simpler to have static linking without the virtual keyword, which is naturally a base class object that calls the base class function, and the derived class object calls the derived class function. If you have the virtual keyword, but the argument list is not the same, you will naturally invoke the function of the derived class.

2 constructors, destructors, copy constructors, overloads = Some problems with inheritance 2.1 constructors and copy constructors

A constructor cannot be a virtual function. When you create a derived class object, the constructor of the base class is called first, and then the constructor of the derived class is called. If the base class does not have a default constructor, the base class needs to call the constructor of the base class through the parameter list and pass the arguments to the base class constructor.

classbase_1{ Public: Base_1 () {std::cout <<"Base_1 defaut Constructor"<< Std::endl; }};classbase_2{ Public: Base_2 (intN) {std::cout <<"base_2 self define Constructor:"<< n << Std::endl; }};classBaseplus_1: Publicbase_1{ Public: Baseplus_1 () {std::cout <<"Baseplus_1 defaut Constructor"<< Std::endl; }};classBaseplus_2: Publicbase_2{ Public: Baseplus_2 (): base_2 (2)//default constructor{Std::cout <<"baseplus_2 defaut Constructor"<< Std::endl; }};classBaseplus_3: Publicbase_1{ Public: Baseplus_3 (intN) {std::cout <<"Baseplus_3 self define Constructor:"<< n << Std::endl; }};classBaseplus_4: Publicbase_2{ Public: Baseplus_4 (intN): base_2 (n) {std::cout <<"Baseplus_4 self define Constructor:"<< n << Std::endl; }};intMain () {baseplus_1 ob_1; Std::cout <<"------------------------------------"<< Std::endl;    Baseplus_2 ob_2; Std::cout <<"------------------------------------"<< Std::endl; Baseplus_3 Ob_3 (3); Std::cout <<"------------------------------------"<< Std::endl; Baseplus_4 Ob_4 (4); System"Pause");return 0;}

The results of the operation are as follows:

The same is true for copy constructors. Must not be virtual, cannot be inherited. The invocation mechanism is the same as the constructor. The copy constructor is usually called in the following case:

    • When initializing with an object
// 此时会调用拷贝构造函数
    • When one object is used to construct another object

      // 此时会调用拷贝构造函数
    • When passing an object

       Base Base::fun() {   ....   returnthis// 此时会调用拷贝构造函数 }
    • When you create a temporary object

// 此时会调用拷贝构造函数,该对象为临时对象
2.2 Destructors

The destructor should be a virtual function, unless the class is not used as a base class. If the derived class object is destroyed, the derived class destructor is called and then the base class destructor is called, so that the runtime is correct. However, if a reference or pointer to a base class points to a derived class object, it will only invoke the destructor of the base class when the object is destroyed, and this part of the memory is leaked if memory is allocated dynamically in the derived class constructor. If the destructor of the base class is virtual, the derived class destructor is called first, and then the destructor of the base class is called.

classbase_3{ Public: ~base_3 () {std::cout <<"Base_3 destructor"<< Std::endl; }};classbase_4{ Public:Virtual~base_4 () {std::cout <<"Base_3 destructor"<< Std::endl; }};classBaseplus_5: Publicbase_3{ Public: ~baseplus_5 () {std::cout <<"Baseplus_5 destructor"<< Std::endl; }};classBaseplus_6: Publicbase_4{ Public: ~baseplus_6 () {std::cout <<"Baseplus_6 destructor"<< Std::endl; }};intMain () {Base_3 * pbase_3=NewBaseplus_5; Base_4 * Pbase_4 =NewBaseplus_6;DeletePbase_3; Std::cout <<"------------------------------------"<< Std::endl;DeletePbase_4; System"Pause");return 0;}

The results of the operation are as follows:

You should typically provide a virtual destructor to the base class, even if it does not require a destructor

2.2 Overloaded operator = function (Assignment function)

= The operation symbol is the same as the copy constructor, if the derived class does not overload the operator. Invokes the operator function of the base class (either overloaded or default), and if the derived class defines a function that invokes the overloaded class of the derived classes. Therefore, in order to maintain the correct assignment of the base class partial data, the overloaded function of the calling base class must be displayed in the overloaded function of the derived class. Such as:

BasePlus & BasePlus::operator= (const BasePlus & ob){  Base::operator// 显示调用基类构造函数  ...}

The only difference here is that operator= (), a function can be a virtual function. So what's the situation where we need operator= to be a virtual function? The assignment function of a derived class is expected to be called by a polymorphic call only when the two base class reference to the derived class object is assigned a value that requires the assignment of the derived class part data. Unfortunately, this operation is not possible at this time, as follows:

virtualoperator= (constoperator= (const BasePlus & ob);

Although a base class assignment function is a virtual function, a derived class function is not a redefinition of the function. Perhaps the reason the compiler does not map virtual base & operator= (const base & OB) to the virtual function table is that the constructor of the base class is called when two references to the base class of the derived class object are assigned. As follows:

//base classclassbase{ Public:VirtualBase &operator= (ConstBase & OB) {std::cout <<"Baseplus operator = is running"<< Std::endl;return* This; }};//derived classclassBaseplus: Publicbase{Baseplus &operator= (ConstBaseplus & OB) {Base::operator= (OB);//Show Call base class functionStd::cout <<"Baseplus operator = is running"<< Std::endl;return* This; }};intMain () {Baseplus objbaseplus_0;    Baseplus Objbaseplus_1;    Base & obj_0 = Objbaseplus_0;    Base & obj_1 = Objbaseplus_1;  Obj_0 = obj_1; System"Pause");return 0;}

The output results are as follows:

Some of the details in the C + + class (overloading, overriding, overwriting, hiding, constructors, destructors, copy constructors, assignment functions in the inheritance of some problems)

Related Article

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.