Don't be fooled by C + + (automatic generation rules) _c language

Source: Internet
Author: User
Tags class definition inheritance object model

C + + objects can be created in two ways: constructors and copy constructors. Suppose we define class A and use it to create an object.

Copy Code code as follows:

A a,b;
A C=a;
A d (b);

Objects A and B are created using the compiler-supplied default constructor a::a (), which we call the creation of the object's definition (which contains the meaning of the Declaration). Objects C and D are created using an existing object, through the compiler-supplied copy constructor, a::a (const a&), which we call the creation of an object's initialization (which contains the definition and declaration meaning).

Many people may confuse the initialization of objects with the assignment of objects, for example.

Copy Code code as follows:

C=d;

Here, assigning object D to object C is not creating a new object, it does not call any constructors. The compiler provides the default assignment operator overload function Const a&operator= (const a&) to support this statement.

In addition to providing default constructors, copy constructors, and overloaded functions for assignment operators, the compiler may also provide us with destructor a::~a (), but the destructor here is not virtual (I believe some children's shoes will forget this).

These basic syntaxes may be no stranger to people who have studied C + +, and we have always known that compilers provide such conveniences to us since we have studied object-oriented C + +. After years of programming practice and experience, we absolutely believe that the compiler does this for us because we have not encountered any problems. Even if I define an empty class (nothing in the Class), the compiler will still "obediently" generate the four functions mentioned above by default.

If you really form this concept, then congratulate you, because you have to use C + + basic rules are very skilled. And unfortunately you and I have all seen the tip of the iceberg, and the compiler works much differently than we use it. The reader may wonder, does the compiler not generate these functions? A: It depends on the definition of your class. So how exactly does the compiler generate these functions? People like me and curiosity want to find out, and these content in the "Inside the C + + Object Model" was interpreted more thoroughly. The author also through "Jiehuaxianfo" the way the book described the object of the construction of the insider with the personal understanding and share with everyone.

First we start with the simplest, does the compiler generate constructors for the class? If, according to the example above, there is only one empty class definition, we can say for sure--No. We don't have to be surprised by the way the compiler does this. Think of an empty class--no data members, no member functions, what can you do even if you build a constructor? Even if it's generated, it's just an empty constructor.

Copy Code code as follows:

A () {}

It can't do anything, and it doesn't have to do anything. More "tragic", it appears not only without any positive significance, but also for compilers and programs to run add completely unnecessary function call burden.

So, let's make this class a little bit more complex, and we'll add data members and member functions to it, like the following code (we'll remember it as Example 1).

Copy Code code as follows:

Class A
{
Public
int var;
void Fun () {}
};

Even so, the result is the same as the top, do not generate constructors! Because there is no reason to initialize VAR, the compiler does not know what value to initialize it with.

-->

Sure enough, no constructors were invoked after object A was defined within the main function.

One might say that initializing with 0 doesn't work? This is only our "wishful thinking". The value of an uninitialized variable itself can be indeterminate, so why generate a statement that is initialized to 0 without any meaning?

How exactly does a compiler build a constructor?! Maybe you're a little "crazy" like me. But now is not the time to despair, because the compiler needs us to give it a "legitimate reason" to build the constructor. There are four valid reasons why the compiler had to generate constructors, as described here.

First, we'll change the type of var. This assumes that it is not a built-in type int, but rather a well-defined class B.

B var;

Change the type of the data member to a custom type can affect the compiler's choices? A: maybe. This depends on whether Class B has a constructor defined. The reader may be a little bit clear, yes, if B does not define a constructor (and a look like this here), then the compiler still has no reason to generate constructors--what is initialized for B? Conversely, once B defines the default constructor b::b (), even if it is empty, the compiler has to create a default constructor for a (this does not take into account the compiler's depth optimization). Because the object of a needs to initialize its own member Var with the default constructor of B, although the constructor of B does nothing. Because the compiler cannot assume what the constructor of B does (the extreme point: what happens if a global variable is modified?) , so the compiler has an absolute need to generate a constructor that guarantees that the constructors of the type B data member are properly executed.

When we go to the constructor generated by a compiler, we find the statement that the constructor of B is called (The row selected).

Of course, if B provides constructors, but not the default constructor, then the programmer must be involved in the initialization of VAR, otherwise the compiler will be rude.--error!

Therefore, the first justification for the compiler to generate a default constructor is that the data member within the class is an object, and the class of that object provides a default constructor .

Now, let's go back to Example 1, where we don't modify the type of Var, but let a inherit from another Class C.

Copy Code code as follows:

Class A:public C

As we all know, in the C + + constructor initialization syntax, the constructor initializes the base class C before initializing its own data member or object. So here's the problem and the object member Var is similar. If the base class C does not provide any constructors, the compiler still does not provide a default constructor. If C provides a default constructor, the result is similar to the front.

As expected, the compiler generated a constructor for a and invoked the default constructor defined by base class C. Similarly, if C does not provide a default default constructor, and other constructors are provided, the compilation cannot be passed.

This is also the second justification for the compiler to generate a default constructor--the base class for the class provides the default constructor .

We are back to Example 1 again, this time we modify the member function fun.

Copy Code code as follows:

virtual void Fun () {}

We modify the member function fun of Class A to virtual function, and see again if the default constructor is generated.

This time the compiler "rudely" generated a default constructor for a, although it did not invoke any other constructors! What's the reason? Originally, C + + in order to realize the polymorphic mechanism, you need to maintain a virtual function table (vftable) for the class, and each object of that class holds a pointer to the virtual function table (typically saved at the four four section of the object's first start, the implementation of the polymorphic mechanism is not described here). The compiler generates a constructor for a, but not for anything else, just to ensure that the object it defines should initialize the pointer to the virtual function table (VFPTR)!

OK, so we've come to the third justification for the compiler to generate the default constructor-- The virtual function is defined within the class . There may also be a more complex scenario where a virtual function is not defined within a class, but a virtual function of the base class is inherited. In fact, according to the above principles, we can infer as follows: Since the base class defines a virtual function, the base class itself needs to generate a default constructor to initialize its own virtual function table pointer. Once the base class produces a default constructor, the derived class needs to generate a default constructor to call it. Also, if the reader knows about the polymorphism mechanism, the derived class initializes the virtual function table pointer within the generated default constructor.

Finally, we go back to Example 1 again, this time still let a a inherits from C, but this time C is an empty class--nothing, and does not automatically generate a default constructor. But the way a inherits C needs to change.

Copy Code code as follows:

Class A:public Virtual C

A virtual inheritance in C, this time what is the difference?

This time the compiler also generates a constructor, and the initialization process is somewhat similar to the virtual function. Carefully observed that this constructor also initializes a table--vbtable. The reader who understands the virtual inheritance mechanism should not be unfamiliar, this table is called the virtual base class table, which records the offset position of all the virtual base class child objects that the class inherits in the object defined by this class (as for the implementation of the virtual inheritance mechanism, we will discuss it in detail later). In order to ensure the correct operation of the virtual inheritance mechanism, an object must maintain a pointer to the table in the initialization phase, called a virtual table pointer (vbptr). The compiler resembles a virtual function because it provides the reason for the default constructor for a.

In this way, we derive the fourth justification for the compiler to generate the default constructor-- the class uses virtual inheritance .

Here we explain the justification for the compiler to generate a default constructor for the class, and I believe you should have a general idea of the timing of the constructor generation. These four "legitimate reasons" are actually the compiler has to generate a default constructor for the class reason, "Inside the C + + Object Model" called this reason for Nontrival (Hou Sir translation is very awkward, so how to translate with you). In addition to these four cases, the compiler is called trival, and there is no need to generate a default constructor for the class. The content of the constructor generation guidelines discussed here is written in C++standard, so it seems that the standard is a set of criteria for "fitting normal thinking" (Simple yy), in fact this is the case, the compiler should not do some unnecessary work for the sake of uniformity.

Through the discussion of the default constructor, I believe everyone. The timing of the generation of the duplicate constructors, assignment operators overloaded functions, and destructors should be expanded automatically. Yes, they follow one of the most fundamental principles: the compilerdoes not really build it until the compiler has to generate a function for that class (nontrival).

So, as the title says, let's not be fooled by the rules and regulations described in the C + + syntax. It's true that these build rules don't make much of an impact on our programming (no bugs), but only by knowing what the compiler is doing for us, we know how to use C + + in order to be more efficient-- such as eliminating unnecessary constructs and virtual mechanisms, etc. (if possible). I believe this article on the content of C + + automatically generated by the description of many people recognize the cause and effect of the object constructor, I hope this article is helpful to you.

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.