[Go] do not be deceived by C + + "auto-generation"

Source: Internet
Author: User

Http://www.cnblogs.com/fanzhidongyzby/archive/2013/01/12/2858040.html

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

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

Objects a and b are created using the compiler-provided default constructor, a::a () , which we call the definition of the object (including the meaning of the Declaration). Objects C and D are created by using the existing object, the copy constructor a::a (const a&) provided by the compiler, which we call the initialization of the object (containing the meaning of the definition and declaration).

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

C=d;

Assigning Object D to object C here does not create a new object, it does not call any constructors. The compiler defaults to the assignment operator overload function Const a&operator= (const a&) to provide support for the statement.

In addition to providing a default constructor, a copy constructor, and an assignment operator overload function, the compiler may also provide us with a destructor a::~a (), but the destructor here is not virtual (I believe there will be children's shoes to forget this).

These basic grammars may not be unfamiliar to people who have studied C + + , and since we've learned about object-oriented C + + , we've always known that compilers provide us with such conveniences. 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 in our minds, a concept is formed by default-even if I define an empty class (nothing in the Class), the compiler will still "obediently" generate four of the above-mentioned functions for us.

If you really have this idea, then congratulations, because you've used the basic rules of C + + very skillfully. And it's a pity that you and I have seen the tip of the iceberg, and the way the compiler works is far less like 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 the content in the "Inside theC + + Object Model" is interpreted more thoroughly. The author also through the "Jiehuaxianfo" way the book describes the object of the structure of the inside of the combination of personal understanding and everyone to share.

First we start with the simplest, does the compiler generate constructors for classes? If we follow the example described above with only an 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, even if a constructor is generated and what can be done? Even if it is generated, it is just an empty constructor.

A () {}

It can't do anything, and it doesn't have to do anything. More "tragic", its appearance not only has no positive significance, but also for the compiler and program run to add a completely unnecessary function call burden.

In that case, let's make this class A little more complicated, and we'll add data members and member functions to it, such as the code below (we'll take it as example 1).

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

Even so, the result is the same as the top, and does not generate a constructor! Because there is no reason to initialize var , and the compiler does not know what value to initialize it with.

Sure enough, after defining object a within the main function, no constructors are called.

Could someone say that initializing with 0 doesn't work? It's just our "wishful thinking". The value of a non-initialized variable itself can be indeterminate, so why create a statement that has no meaning and is initialized to 0 .

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

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

B var;

Does modifying the type of the data member for a custom type affect the compiler's choice? Answer: maybe. It depends on the classBThere is no constructor defined. The reader may be a little bit clear, yes, ifBThere are no constructors defined (and theA), the compiler still has no reason to generate a constructor--BWhat does it initialize? InsteadBOnce the default constructor is definedb::b (), even if it is empty, the compiler has toACreates a default constructor (this does not take into account the compiler's depth optimizations). BecauseAObject needs to use theBThe default constructor initializes its own membersvarAlthoughB's constructor did nothing. Because the compiler cannot assume thatBWhat the constructor does (extreme: What if a global variable is modified?). ), so the compiler has an absolutely necessary buildAThe constructor that guaranteesBThe constructor for the data member of the type is performed normally.

Go to the constructor that the compiler generated for a , we found the statement called by the constructor of B (the selected row).

Of course, if B provides a constructor, but not the default constructor, then the programmer must intervene to initialize the 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 that the class of the object provides a default constructor .

Now, let's go back to example 1, where we don't modify the var type, but instead let A inherit from the other class C.

Class A:public C

As we all know, in the C + + constructor initialization syntax, the constructor initializes the base class Cbefore initializing its own data member or object. Therefore, the problem here is similar to the object member var . If the base class C does not provide any constructors, the compiler still does not provide a 's 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 called the default constructor defined by the base class C . Similarly, if C does not provide a default default constructor, and other constructors are provided, compilation cannot be passed.

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

We return to example 1again, this time we modify the member function fun.

virtual void Fun () {}

Let's change the member function fun of class A to virtual function and see if we have a default constructor.

This time the compiler was "not polite" to generate a default constructor for a , although it did not call any other constructors! What is the reason for this? Originally,C + + in order to implement a polymorphic mechanism, you need to maintain a virtual function table (vftable) for the class, and each of the objects of this class holds a pointer to the virtual function table (typically saved at the beginning of the object four four sections, The implementation of polymorphic mechanisms is not described here). The compiler generates a constructor for a, which is nothing else, to ensure that the object it defines is properly initialized with the pointer to the virtual function table (vfptr)!

Okay, so we get the third justification for the compiler generating the default constructor-- a virtual function is defined within the class . There may also be a more complex point: the class itself does not define a virtual function, but inherits the virtual function of the base class. 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 has a default constructor, the derived class will need to generate a default constructor to call it. Also, if the reader understands the removal of the polymorphic mechanism, the derived class will also initialize the virtual function table pointer within the generated default constructor.

Finally, we return to example 1, this time still let a inherit 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 has to change a bit.

Class A:public Virtual C

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

This time the compiler also generated a constructor, and the initialization process and the virtual function are somewhat similar. Careful observation found that the constructor also initializes a table-vbtable. Readers who understand the virtual inheritance mechanism should not be unfamiliar, this table is called the virtual base class table, it records the class inherits all the virtual base class sub-object in this class defines the object the offset position (as for the virtual inheritance mechanism implementation, we discuss later in detail). To ensure the correct work of the virtual inheritance mechanism, the object must maintain a pointer to the table in the initialization phase, called the virtual table pointer (vbptr). The compiler is similar to a virtual function because it provides the reason for A's default constructor.

Thus, we derive the fourth justification for the compiler to generate a default constructor-the class uses virtual inheritance .

Here, we put the compiler for the class to generate a default constructor for the justification, I believe you should have a general understanding of the generation time of the constructor function. These four "justification" is actually the reason why the compiler has to generate a default constructor for the class, and theInside the C + + Object Modelsays the reason is nontrival ( Sir The translation is very awkward, so how to translate it with you. In addition to these four cases, the compiler is called trival , which means that there is no need to generate a default constructor for the class. The building code discussed here is written into C++standard , so it seems that the standard is "fit normal thinking" set of guidelines (simple YY ), in fact, this is the case, the compiler should not do some unnecessary work for the sake of consistency.

Through the discussion of the default constructor, it is believed that the generation time of copy constructor, assignment operator overload function and destructor should be expanded automatically. Yes, they follow a fundamental principle: only when the compiler has to generate a function for this class (nontrival), does the compiler actually generate it .

So, as the title says, we should not be "fooled" by the rules described in C + + syntax. Indeed, it is believed that these build rules do not have much impact on our programming (no errors), but only when we understand what the compiler does for us, do we know how to use C + + to make it more efficient- such as eliminating unnecessary constructs and virtual mechanisms (if possible). I believe that the description of C + + Auto-generated content allows many people to understand the cause and effect of the object constructor, I hope this article will help you

[Go] do not be deceived by C + + "auto-generation"

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.