C ++ User-Defined Conversion (User-Defined Conversion)

Source: Internet
Author: User

 

In computer languages, the existence of types allows us to process data and functions more specifically, but there is a problem of type conversion. C ++ has the same problems as other computer languages. However, it has more Reference types than C, and more Point types than C ). This seems to make its type conversion more confusing.

It may be a continuation of the C knowledge. I am quite clear about the conversion between the basic types of C ++, but the C # Convert class library is so easy to use, so that I have never adapted to the C ++ conversion method. However, the instructor's professor found that C ++ can also build a conversion method similar to Convert.

After the instructor passed a class on C ++ type conversion, I checked the relevant information on the Internet to give a clearer and more detailed summary of the C ++ type conversion method.

Traditional conversion method (Traditional Type-Casting)

C ++, as a superset of C language, fully inherits the type conversion methods and capabilities of C language. Therefore, it is easy to understand the conversion of this Part in the basic numeric type. However, because C ++ is an object-oriented language and has the concept of classes, a new layer of content needs to be understood.

Implicit Conversion (Implicit Conversion)

Implicit conversion does not require any conversion operators. The Compiler automatically converts different types based on the Type compatibility. Generally, in C/C ++, this type of conversion exists in the basic numeric type, and the basic principle is that the type with a small memory size can be directly converted to the same memory size or.

The types with the same memory size can also be converted to each other, but the result may not be expected, so the compiler may receive a warning. For example, unsigned int uintVariable =-1 ;.

Although: programmers only care about errors and do not care about warnings, the mentor also strictly prohibits such implicit conversions.

Explicit Conversion)

Display the type of the target object to be converted. The Compiler then converts the object in two formats:

• C-like Cast)

(New_type) expression

• Function-style Cast)

New_type (expression)

Sample Code

# Include <iostream>

Using namespace std;

Int main (){

Int x0 = 100;

Float num0 = x0;

Float num = 98.76;

Int x1 = (int) num;

Int x2 = int (num );

Cout <"num0 =" <num0 <endl;

Cout <"x1 =" <x1 <endl;

Cout <"x2 =" <x2 <endl;

Cout <"x3 =" <x3 <endl;

}

For C ++ classes, you can also use traditional type conversion on their instance objects, which utilizes some language features of C ++.

The following is an example.

Code

# Include <iostream>

# Include <string>

Using namespace std;

 

// Macro definitions

# Define IDER_DEBUG 1

# Define FUNC_TRAC (info) {if (IDER_DEBUG) cout <"----" <info <"----" <endl ;}

 

// Class declaration

Class Human;

Class Ape;

Class Programmer;

 

// Class definition

Class Programmer

{

Public:

Programmer (string where = "genius ")

{

FUNC_TRAC ("Programmer Default Constructor ");

From = where;

}

/* Programmer (Programmer & p)

{

FUNC_TRAC ("Programmer Copy Constructor ");

From = p. from;

}*/

Void Speach () {cout <"I am a Programmer, I am" <from <endl ;}

Private:

String from;

};

 

Class Human

{

Public:

Human (string where = "delivered by Parents"): heart ("Human with Training ")

{

FUNC_TRAC ("Human Default Constructor ");

From = where;

}

Human (Ape & a): heart ("Human with Practice ")

{

FUNC_TRAC ("Hummer Ape-Promotion Constructor ");

From = "Evolution from an Ape ";

}

Operator Programmer () // here is weird, it is really different whether we have "&" or not

{

FUNC_TRAC ("Hummer Programmer-Cast Operator ");

Return heart;

// Programmer ("Human with Practice"); // it is not good to return temporary variable

}

Human & operator = (Human & h)

{

FUNC_TRAC ("Hummer Assignment Operator ");

Cout <"Call assignment" <endl;

Return * this;

}

Void Speach () {cout <"I am a Human, I am" <from <endl ;}

Private:

String from;

Programmer heart; // Every one has a heart to be a programmer

};

 

Class Ape

{

Public:

Ape (string where = "from Nature ")

{

FUNC_TRAC ("Ape Default Constructor ");

From = where;

}

Ape & operator = (Programmer & p)

{

FUNC_TRAC ("Ape Programmer-Assignment Operator ");

From = "Degeneration from a Programmer ";

Return * this;

}

/* Ape & operator = (Ape & p)

{

FUNC_TRAC ("Ape Assignment Operator ");

Cout <"Ape assign" <endl;

Return * this;

}*/

Void Speach () {cout <"# (* % ^ ,! @ # $ &) ("<From <endl ;}

Private:

String from;

};

 

 

// Main function

Int main (void ){

Ape;

// A. Speach ();

Human h = a; // using promtion constructor

// H. Speach ();

Human h2;

H2 = a; // Error, no match assignment opeartor

Programmer p = h; // using Programmer-cast operaotor

// P. Speach ();

Programmer p0;

P0 = h; // using Programmer-cast operaotor

Programmer p1 = h. operator Programmer ();

Programmer p2 = Programmer (h );

Programmer p3 = (Programmer) h;

 

Ape a2;

A2 = p; // using assignment operator

// A2.Speach ();

Ape a3 = p; // Error, no match constructor

 

Return 0;

}

 

In this example, I have defined three classes. There is no inheritance or inheritance relationship between these three classes, and there is no friend relationship. The basic connection is: ape can evolve to Human, and Human can become Programmer after continuous training, but Programmer may also degrade to Ape.

Analysis

From their conversion operations in the main function, we can see that this is an implicit conversion. However, the real reasons for the conversion between the objects of the three classes are not the same.

First, the conversion from Ape to Human

Human h =;

Actually, the promotion constructor of Human is called.

Human (Ape & );

This function accepts Ape as the constructor parameter and instantiates a Human object.

From Human to Programmer, it is because I have defined a conversion operator to Programmer in Human: operator Programmer ()

Therefore, the two assignment statements in the main function are: Programmer p = h; p0 = h;

All of them call this conversion function.

Degradation from Programmer to Ape is a reluctance (because in Chinese, we are programmers), the implementation method in code, in the Ape class, a reload Form of Assignment operator that accepts Programmer references as parameters is defined. Ape & operator = (Programmer & p)

So the following statement a2 = p;

It can be run in the program.

Further Analysis

We have seen that the conversion between Ape, Human, and Programmer uses different C ++ features and calls different methods. However, these methods are different from each other.

Based on Human to Programmer, this conversion uses user-defined cast (user-defined cast), so it can be said that this method is the conversion between real types.

Therefore, the conversion of the two syntax formats is valid in main:

• Define and initialize

Programmer p = h;

• Assignment

P0 = h;

However, the Ape-Human transformation calls the constructor, so it is only valid when the class instantiates the object and initializes it. Therefore, the following statement will get the compiler error: Human h2; h2 = a; // Error, no match assignment opeartor

Because Human knows how he came from his birth, and should not later discover that he was not a mother (of course, these situations are not impossible, such as "").

Programmer and Ape are formed the day after tomorrow. Otherwise, they will become monkeys at birth, so they can only use their toes for Coding. The following code cannot be compiled: Ape a3 = p; // Error, no match constructor

Let's talk about Human to Programmer. We can also write in more different forms, such as two forms of display conversion: Programmer p1 = Programmer (h ); programmer p2 = (Programmer) h;

(Initialization or assignment doesn't matter)

However, after compilation, the format should be: Programmer p3 = h. operator Programmer ();

This is also true for the Assignment operator. The actual call is: a2.operator = (p );

Postscript

In fact, in actual programming, it may be affected by C # (because C # initialization does not get a brand new object, but just gets reference ), user-Defined conversions are not often used, and an Assignment operator that accepts non-object references is rarely reloaded.

Most of the conversions are implemented through constructors. Or, instantiate the object and assign values to the data through the interfaces of the two. After all, in the preceding methods, you can only call the external interface of the received object and cannot perform private data operations.

We have already mentioned the conversion of numeric type and class object, but what does it seem to be missing?

Yes, C ++ also has reference and pointer ). The conversion between the two types is not mentioned yet.

In C ++, there seems to be no difference in Pointer types, because it only stores the address of the object to be referred to, so the required memory space and format are consistent, therefore, pointers between different types of C ++ can be converted at will. Display conversion is generally required. However, this type of conversion is meaningless, because the type indicated by the address is not the required type. The data or method found through the offset of the address will not be what we need, during running, an exception occurs in the program.

It does not seem reasonable to convert a reference type between non-inherited types. In fact, a reference can be regarded as a pointer in implementation, but in syntax format, it is used as an object. If we convert the reference type, do we want a new object, or do we only need an address? Confusing.

In addition, pointers and references should be used on existing objects or object variables. Therefore, if a local variable (like the line of code I commented out in the operator Programmer () method of the Human class) is returned in the conversion operator method ), after leaving the method of the conversion operator, those variables will be recycled, and it makes no sense to point to those addresses. If it is an internal new object, the management of this object becomes unbinding and we don't know when to delete it. Even if the Human class carries a Programmer object Heart, however, this design does not seem very good, because it cannot ensure that everyone has a heart as a programmer.

Legacy problems

We also mentioned the pointer and reference issues in type conversion. Therefore, for user-defined Conversion characters, in my code, I use Object-based conversion: operator Programmer ();

Not pointer-based: operator Programmer *();

It is not based on referencing operator Programmer &()

In my opinion, this is reasonable and appropriate.

However, if I define a copy constructor In the Programmer class, all the four code formats from Human to Programmer mentioned above will get compilation errors.

This seems understandable: the compiler will find the appropriate entry from the constructor, but it fails, so it is wrong.

But why h. operator Programmer ();

The format is also incorrect, which makes me very puzzled.

Further, if I change object-based conversion to reference-based conversion, the compiler will not report an error. But I think this should be logically incorrect.

C ++ is really a complicated language (of course it is not comparable to JavaScript). If you know the cause of this problem, please share your understanding and opinions with me.

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.