Why does the C ++ copy constructor disappear to C #?

Source: Internet
Author: User

From: http://blog.csdn.net/zhuweisky/article/details/415661

It is undeniable that C ++ has been a mainstream development language on the Windows platform for the past decade and even now, and it is fierce. net is bound to open up a new situation, from the current indications ,. net is the trend of the times, while C #. the first development language on the net platform has naturally received much attention, so many programmers have switched to C #. Of course, there are many c ++ programmers. This is often the case. programmers often unconsciously fall into the mindset of the original development language, from one language to another, even in a similar language, there is usually only one such result, that is, the errors that even programmers can never figure out. This article was proposed by a C ++ programmer, "Isn't C # A copy of the constructor ?" This issue leads to a comparison between C ++ and C # language features.

 

 

1. What happened?

 

 

If you are a C ++ programmer who is switching to C #, you must feel incomprehensible for classes in C # that do not copy constructor or rarely call value assignment operators, and many of the statements you see are not executed as you think, such

// Suppose student is a class (C #)

Student S1 = new student ();

Student S2;

S2 = S1; // what will happen to this statement?

Because you are a skilled C ++ programmer, you have already determined in the subconscious that the statement student S2 will generate a student object (that is, an instance) in the stack, and the statement S2
= S1; the value assignment operator is called. After the preceding statement is executed, the following memory layout is generated:

Wrong. All Wrong !!!

This is not the case in C. First, I will explain how the above statements are executed in C.

Student S1 = new student ();

The above code will generate an object in the heap, And let reference S1 point to this object, and reference S1 itself is located in the stack, occupying four bytes (on a 32-bit processor, the length of a pointer ).

Student S2;

This statement will generate a 4-byte reference variable S2 in the stack, and the default value is null, that is, the reference does not point to any instance.

S2 = S1;

This assignment statement does not call the assignment operator. Instead, it only points S2 to the object pointed to by S1. Therefore, after the preceding statement is executed, the memory layout is roughly as follows:

To understand why, you must first know the difference between C # And C ++ references.

 

 

Ii. Differences between C # And C ++

 

 

From the simple example above, we can see how different the "reference" is in C # And C ++. The main difference can be expressed as one sentence:

References in C ++ are tightly bound, while references in C # are loosely bound.

The references in C ++ are declared with the "&" symbol, and must be initialized as a valid object. Once the reference is initialized, therefore, in C ++, the compiler considers that all references are valid and does not need to perform type checks, this is the reason why the reference in C ++ is not flexible but more efficient than the pointer. In C ++, because references are tightly bound to objects, we can considerReference is the object itself.Just as the stack Object Name Is the stack object itself. You can also think that the reference in C ++ is just an alias of an object. This name only exists because of the existence of this object.

See the following C ++ code.

// C ++

Student S1;

Student & S2 = S1; // S2 is the alias of stack object S1

......

Student S3;

S2 = S3; // invalid !!! S2 can no longer be the alias of the object S3

S3 = S2; // call the value assignment operator

It is precisely because of the tight binding feature in C ++ that the last statement above will call the value assignment operator to make the object S2 and S3 in the same state.

 

 

Let's look at C #.

In C #, there are only two types of data: Value Type and reference type. Value types are generally basic data types, such as int, double, and struct. All custom classes, arrays, representatives, and interfaces, are reference types. Because of this convention, you do not have to be surprised that the "&" quote in C # does not exist.

All value type objects are always allocated only in the stack, even if you use new for the value type;

// C #

Int age = new int (24); // still allocate space for age in the stack, equivalent to the statement int age = 24.

Similarly, all reference type objects are always created in the heap. To generate an instance of the reference type, you must use new, and the reference returned by new is usually stored in the stack. Declaring a reference type object is equivalent to declaring a null pointer (that is, the reference in C # Can be null, which is not allowed in C ++ ), only four bytes are allocated to the reference in the stack. The reference cannot be used before the reference is assigned a value (that is, it does not point to the valid heap memory) because the reference is empty.

// C #

Student S5; // declares only one reference and does not create any object

S5 = new student (); // create an object in the heap and let S5 point to this object

In fact, references in C # are more like pointers in C ++, that is

References in C # are references with pointer semantics.

Therefore, the Reference Assignment in C # is like the pointer assignment in C ++, just pointing it to another object. That is to say, C # uses the shortest-level copy. When referencing mutual value assignment, only the referenced value (indicating the Logical Memory Address data) has changed, but has no influence on the status of the referenced object-if there is an influence, that is, it only changes the GC reference count for this object.

It is precisely because the references in C # Have pointer semantics that GC facilitates the reference counting of objects. When the reference count of an object changes to 0, GC releases the object, which is the basic principle of automatic memory management in C.

 

 

Iii. Transfer of reference and Value

When passing an object by value in C ++, the copy constructor is called to generate a copy of the object. Is that true in C?

Whether in C ++ or C #, there are two ways to pass a variable or object as a function parameter: pass by value or by reference.

The so-called pass by value means that the object copy is used inside the function body. In C ++, this copy is completed by calling the object copy constructor, the modification of the copy by the function does not affect the original object. For example

// C ++

Void fun1 (student SS)

{

... // Process and modify the SS-the actual processing is a copy of the input object

}

......

Student S7;

Fun1 (s7); // after this function is called, the status of object S7 does not change.

......

The so-called pass by reference refers to the address of the object that is passed to the function, so that the function changes the object and the object state changes. For example

// C ++

Void fun2 (student & SS)

{

... // Process and modify the SS

}

......

Student S8;

Fun2 (s8); // after this function is called, the status of the object S8 changes.

......

In C ++, you can use pointers and "&" referers to transmit references. In the above example, the reference symbol "&" can be used to replace it with a pointer to achieve the same effect. If we further think about it, we can find that when a pointer is used for reference transfer, replication also occurs, except that the value of the pointer (that is, the address of the object) is copied ), instead of copying the object pointed to by the pointer. This can be proved by the following example.

// C ++

Void fun3 (student * ss)

{

...... // Process and modify the object pointed to by the SS

Ss = NULL;

}

......

Student * S9;

Fun3 (S9); // after this function is called, the status of the object pointed to by S9 changes.

......

However, after fun3 (S9) is called, S9 is not null, which indicates that fun3 uses a copy of the pointer S9. Further, we can guess that the same story also happened when the "&" character was used to implement reference transfer. In fact, the reference in C ++ is only a restricted but safer pointer.

So what are the advantages of transferring by reference and passing by value?

The copy action is not required for transferring by reference, so the speed is fast, especially for large objects. When passing by value, the modification to the passed object is actually the modification to the object copy, without affecting the status of the original object.

You may think that if you use const reference transfer, you will get double benefits. You can say so, but do not go to the extreme.

Generally, it is appropriate to pass a large object that cannot be changed as a const reference to a function. However, if it is a simple type or a custom small object, it can be passed directly with a value.

If the outside world must see the function's modification to the object, there is only one path-pass by reference.

 

 

In C #, the situation has changed. Objects of the reference type in C # are passed by reference and can only be passed by reference. Value Type objects (or variables) are usually passed by value. If you want to pass a value type object by reference, you need to use the keyword ref or out. The only difference between ref and out is that when ref modifies a parameter, the input variable is initialized.

Because the class is a reference type, and all the objects of the reference type are passed by reference, there is no call to the copy function in this process. In this case, there is no need to copy the constructor.

Now you know why the constructor does not need to be copied or the value assignment operator is rarely called in C. You may ask if the assignment operator is rarely called, and the assignment operator must be called. What is the situation? That's because the similar body of the class-the structure struct.

 

 

Iv. struct

In C ++, there is almost no difference between struct and class. The only difference is that struct members are public by default, while Class Members are private by default. However, the situation changes essentially in C #, Because struct in C # is of the value type, while class is of the reference type. From the analysis below, we can see that C #'s creators are really ingenious in this design. So what are the benefits?

All value types in C # are created in the stack. The advantage of creating an object in the stack is higher efficiency. Before allocating objects in the heap, you need to use certain algorithms to find suitable memory blocks. This may be time-consuming, and you can directly press the stack to create value-type objects; in addition, the stack object is automatically released when the function returns, and the heap object must be processed by GC. If we design a very small class, and its instances are rarely transferred between functions (because the transferred value type objects between functions by non-reference will be copied ), we can consider implementing it as struct instead of class.

Since struct is a value type, when two struct values of the same type are assigned to each other, the value assignment operator of struct is naturally called.

In addition, after my verification, the copy constructor is not provided in C #, but you can obtain the copy constructor in disguise by reloading constructor, the implementation of this technology is very simple, so I will not talk about it here.

 

 

So you don't have to say, "Why didn't C # copy the constructor ?" "Why do the call of the value assignment operator is rarely seen in C ?" This problem is confusing :)

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.