C ++ base class, derived class, same name overwrite Principle

Source: Internet
Author: User
Tags c constructor

// Overwrite with the same name principle. cpp: Master project file. <Br/> # include "stdafx. h "<br/> # include <iostream> <br/> # include <string> <br/> using namespace std; <br/> class One <br/>{< br/> private: <br/> string name; <br/> int age; <br/> public: <br/> virtual ~ One () = 0 {}< br/> void Get_name () const <br/>{< br/> cout <"Name:" <name <endl; <br/>}< br/> void Get_age () const <br/>{< br/> cout <"Age:" <age <endl; <br/>}< br/> protected: <br/> One (): name ("plato"), age (24) {}< br/> One (string N, int Age): name (N), age (Age) {}< br/>}; <br/> class Two: public One <br/>{< br/> private: <br/> string sex; <br/> public: <br/> Two (): One (), sex ("female "){} <Br/> Two (string Name, int Age, string Sex): One (Name, Age), sex ("Sex") {}< br/> ~ Two () {}< br/> void Get_name () const; <br/> void Get_age () const; <br/> void Get_sex () const; <br/>}; <br/> void Two: Get_name () const <br/>{< br/> One: Get_name (); <br/>}< br/> void Two: Get_age () const <br/>{< br/> One: Get_age (); <br/>}< br/> void Two: Get_sex () const <br/>{< br/> cout <"Sex:" <sex; <br/>}< br/> int main (array <System: String ^> ^ args) <br/>{< br/> Two juck; <br/> juck. get_age (); // default will call drived class method <br/> juck. one: Get_age (); // Explicit declare use base class method <br/> system ("pause"); <br/> return 0; <br/>}< br/> 

 

# Running result:

 

# Now we can see the access mechanism when there is a member of the same name in Multi-inheritance.

 

// Constructor of the virtual base class and its derived class. cpp: Main project file. </P> <p> # include "stdafx. H "<br/> # include <iostream> <br/> using namespace STD; <br/> Class A <br/>{< br/> PRIVATE: <br/> int a_value; <br/> Public: <br/> A (int A): a_value () {cout <"Member of Class A" <Endl ;}< br/> void fun () const {cout <"function of a" <Endl ;} <br/>}; <br/> Class B: virtual public a <br/>{< br/> PRIVATE: <br/> int B _value; <br/> public: <br/> B (int A, int B): A (a), B _value (B) {cout <"Member of Class B" <Endl ;} <br/>}; <br/> Class C: virtual public a <br/>{< br/> PRIVATE: <br/> int c_value; <br/> public: <br/> C (int A, int C): A (a), c_value (c) {cout <"Member of class C" <Endl ;} <br/>}; <br/> Class D: Public B, public C <br/>{< br/> PRIVATE: <br/> int d_value; <br/> Public: <br/> D (int A, int B, int C, int D): A (a), B (a, B ), C (a, c), d_value (d) {cout <"Member of class D" <Endl ;}< br/> void fun () _ dconst {cout <"function of D" <Endl ;}</P> <p >}; </P> <p> int main (array <system :: string ^> ^ ARGs) <br/>{< br/> d tmp (10, 20, 30, 40); <br/> TMP. fun_d (); </P> <p> TMP. fun (); <br/> TMP. b: Fun (); <br/> TMP. c: Fun (); </P> <p> system ("pause"); <br/> return 0; <br/>}< br/>

 

# Analysis:

 

Int main (array <system: String ^> ^ ARGs)
{
D TMP (10, 20, 30, 40 );
TMP. fun_d ();
 
TMP. Fun ();
TMP. B: Fun ();
TMP. C: Fun ();

System ("pause ");
Return 0;
}

First, let's look at TMP. fun_d (); TMP is a third inherited Class Object. Which member function does it call? First, it searches for the current domain and its class region. If the corresponding member function cannot be found, it looks forward. The corresponding member function fun_d () has already been defined in the Class D to which TMP belongs. Therefore, TMP. D: fun_d () is called directly here ();

 

Let's take a look at TMP. Fun (). Similar to the above, it first looks for the fun () function from the current domain (Class D). If it cannot be found, it looks forward until it is found. Fun () is defined in base class A, so a member function of base class A is called here.

 

Let's take a look at tmp. b: fun ().. obviously, the third inheritance Class D and the second inheritance Class B do not explicitly define the function fun (). What is the call here? Because Class B is derived from the base class A public, tired B will inherit the members of Class A, similar to the base class A will map the corresponding members to the corresponding region on the inheritance Class B. (Through public inheritance, the base class A projects the public/protected members to the public/protected region corresponding to the inherited class B. Note that this is A one-to-one projection .). Therefore, tmp. B: fun () hides the principle of the Inheritance Mechanism, and what it calls is actually A member of Class.

 

Of course, the Access Mechanism of tmp. C: fun () is the same as above ..

 

Q: What kind of access will Class C inherit from Class A through the private inheritance mechanism?

 

# Running result:

 

# Slightly modify the following:

 

Class D: Public B, public C <br/>{< br/> PRIVATE: <br/> int d_value; <br/> public: <br/> D (int A, int B, int C, int D): A (a), B (a, B), C (a, c ), d_value (d) {cout <"Member of class D" <Endl ;}< br/> void fun () const {cout <"function of D" <Endl ;}</P> <p >}; </P> <p> int main (array <system :: string ^> ^ ARGs) <br/>{< br/> d tmp (10, 20, 30, 40); <br/> TMP. fun (); <br/> TMP. fun (); <br/> TMP. b: Fun (); <br/> TMP. c: Fun (); </P> <p> system ("pause"); <br/> return 0; <br/>}< br/>

# Note: At this time, the member functions called by the third inheritance Class Object tmp are all fun (); no special case D: fun_d. Next we will differentiate the calling mechanism.

 

First, let's take a look at tmp. B: fun ();

Tmp. C: fun (); // The access mechanism is the same here.

 

Focus on tmp. fun (); when the class limitation domain is not added. When we define a variable with the same name as the global region in a local region,

 

You will know how to differentiate the confusion of the same name. When the program searches for fun () is defined in that region, it first starts from the local region. If the local region does not exist, it searches forward. If it is not found, the compiler will prompt an error. Here, the program first finds D: fun (). The search is successful, and the side is no longer looking forward.

 

# Running result:

 

# The following describes how to differentiate functions with the same name in the base class and derived class during dynamic compilation. The above example is still used for slight modification:

# Include "stdafx. H "<br/> # include <iostream> <br/> using namespace STD; <br/> Class A <br/>{< br/> PRIVATE: <br/> int a_value; <br/> Public: <br/> A (int A): a_value () {cout <"Member of Class A" <Endl ;}< br/> virtual void fun () const {cout <"function of a" <Endl ;} <br/>}; <br/> Class B: virtual public a <br/>{< br/> PRIVATE: <br/> int B _value; <br/> public: <br/> B (int A, int B): A (a), B _value (B) {cout <"Member of Class B" <Endl ;} <br/> void fun () const {cout <"function of B" <Endl ;}< br/>}; <br/> Class C: virtual public a <br/>{< br/> PRIVATE: <br/> int c_value; <br/> Public: <br/> C (int A, int C ): A (a), c_value (c) {cout <"Member of class C" <Endl ;}< br/> void fun () const {cout <"function of C" <Endl ;}< br/>}; <br/> Class D: Public B, public C <br/>{< br/> PRIVATE: <br/> int d_value; <br/> Public: <br/> D (int A, int B, int C, int D): A (a), B (a, B), C (a, c), d_value (d) {cout <"Member of class D" <Endl ;}< br/> void fun () const {cout <"function of D" <Endl ;} </P> <p >}; <br/> const int Lim = 4; <br/> int main (array <system: String ^> ^ ARGs) <br/>{< br/> A First (10); <br/> B second (20, 30); <br/> C third (30, 40 ); <br/> D fouth (60, 70, 80, 90); <br/> A * Po [Lim] = {& first, & Second, & third, & fouth}; <br/> for (INT I = 0; I <Lim; I ++) <br/> po [I]-> fun (); </P> <p> system ("pause"); <br/> return 0; <br/>}

# Now, virtual void fun () const appears in the base class A; this is the focus of this fragment: virtual functions (the basis for implementing dynamic compilation ).

 

When a function call with similar functions as the base class appears in the derived class, we can set this function in the base class to a virtual function, the function of calling the base class is displayed in the derived class.

 

Function, and then add the function statements that need to be independently implemented in this function (that is, the derived class), and so on. Of course, it is best to use public derivation.

 

Code reuse with high efficiency.

 

# Switch to the specific issue for detailed analysis below:

First, let's look at the main function:

Const int Lim = 4;
Int main (array <System: String ^> ^ args)
{
A first (10 );
B second (20, 30 );
C third (30, 40 );
D fouth (60, 70, 80, 90 );
A * po [Lim] ={& first, & second, & third, & fouth };
For (int I = 0; I <Lim; I ++)
Po [I]-> fun ();

System ("pause ");
Return 0;
}

1. first, the four objects first, second, third, and fouth of the base class, second-derived class (two), and third-derived class (D) are explicitly constructed. and declared a base class pointer array (Gu

 

Name: array p0 [Lim] contains four pointers. What pointers? Pointer to the address of the base class and three derived class objects. According to the C ++ derived class object, it can be converted to the base class

 

Class Object principle (Note: downward conversion is irrational, because the derived class may add new members, and these base classes are not available )). Then explicitly call the function fun (),

 

(Note: In the base class, fun () is declared as a virtual function. Therefore, you can add no more virtual keywords before functions with the same name in the derived class. This system will differentiate between them) based on Virtual Functions

 

Usage principle, for example: po [I]-> fun ()/* When I = 2, po (2) = & third */, the system selects which function to call based on the type of the object pointed to by the pointer, instead of the root

 

It is determined by the pointer type, so here C: fun () will be called (). Similarly, when I =, this calls the fun () function in class A, B, C, and D.

 

The running result is as follows:

# Analyze the running results. First, you can view only the first nine rows of the running results:

1. The Member of class A Object first is displayed.

 

 

2. When constructing the respective objects of class B and class C, the constructors of their base classes will be called respectively. Here is A (base class ), then, call the constructor of the class to initialize the newly added members of the class. Therefore, the lines 2, 3, and 4 of the result are clear.

 

3. The following is the fouth object for building class D. Because Class D is abstracted from Class B and C, the object for generating Class D must call class B ,, C constructor to initialize class D

 

Therefore, class B and class C use virtual inheritance Class A, so class d will no longer call class B and class A twice when building the object.

 

 

 

 

 

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.