In depth explanation of C++ data type conversion related functions

  • 2020-05-05 11:35:58
  • OfStack

C++ data type conversion and conversion constructor
Conversions between standard data types

In C++, you can automatically convert between certain types of data, such as


  int i = 6;
  i = 7.5 + i;


7.5 is processed by the compilation system as an double type number. When solving the expression, 6 is converted to double type and then added to 7.5 to get the sum of 13.5. When assigning value to the integer variable i, 13.5 is converted to an integer 13 and then assigned to i. This conversion is done automatically by the C++ compilation system without user intervention. This conversion is called implicit type conversion.

C++ also provides explicit type conversion, in which the programmer specifies the conversion of one specified type of data to another specified type in the form


   Type name ( data )


Such as


  int(89.5)


Its function is to convert 89.5 to 89.

Previously, we dealt with conversions between standard types. Now that users define their own classes, the question is raised: can an object of a custom class be converted to a standard type? Can an object of one class be converted to an object of another class? For example, can you convert a complex number of data into an integer or double? Can you convert objects of class Date to objects of class Time?

For standard types of conversions, the compilation system has rules for how to do the conversion. The compilation system does not know how to convert to the type that the user has declared. The key to solving this problem is to let the compilation system know how to do these transformations, and to define specialized functions to handle them.
Transform constructor

The transform constructor (conversion constructor function) converts a different type of data into an object of a class. Here's a review of some of the constructors we've learned before:
1) default constructor. Taking Complex class as an example, the function prototype is in the form of


  Complex( ); // No parameters 

2) constructor for initialization. The function prototype takes the form of


  Complex(double r, double i); // The formal parameter list column usually has more than two parameters 

3) copy constructor for copying objects. The form of the function prototype is


  Complex (Complex &c); // A parameter is a reference to this class object 

Now we introduce a new constructor, the transformation constructor.

The transformation constructor has only one parameter, such as


  Complex(double r) {real=r;imag=0;}


Its function is to convert the double type parameter r into an object of Complex class, with r as the real part of the complex number and the imaginary part being 0. The user can define the transformation constructor as needed, in the body of the function that tells the compiler how to perform the transformation.

In the body of the class, you can have a transition constructor or you can have no transition constructor, as needed. The above constructors, which can appear in the same class at the same time, are overloads of the constructor. The compiler selects the constructor that matches the number of arguments given when the object is created with the type.

If the above constructor is defined in the Complex class, there are the following declarations in the scope of the Complex class:


  Complex cl(3.5) ; // Object to establish cl , because there is only one argument, the transformation constructor is called 


Create Comptex class object cl, whose real(real part) value is 3.5 and imag(imaginary part) value is 0. What it does is convert an double type constant into an Complex class object called cl. You can also create an unnamed Complex class object with a declaration statement. Such as


  Complex(3.6) ;  // Creates an unnamed object with a declaration statement, which is legal, but cannot be used 

You can use nameless objects in an expression, such as


  cl =Complex(3.6);  // Assuming that cl Has been defined as Complex Class object 


Creates a nameless Complex class object with a value of (3.6+0i), and then sends the value of the nameless object to cl, which is (3.6+0i).

If the operator "+" has been overloaded to add two Complex class objects, if the following expression is in the program:


   Type name ( data )
0


Compilation error because the operator "+" cannot be used to add an Comptex class object to a floating point number. You can first convert 2.5 to an unnamed object of class Complex and then add:


  c = cl + Complex (2.5);  // legal 

Please compare Complex(2.5) and int(2.5). The forms are similar, int(2.5) is a cast that converts 2.5 to an integer, and int() is the cast operator. You can think of Complex(2.5) as a cast, converting 2.5 to an Complex class object.

A transformation constructor is also a constructor that follows the general rules of constructors. A constructor with one argument is usually used as a type conversion, so it is called a conversion constructor. In fact, constructors with one argument, such as
, can also be used without a cast


  Complex (double r){ cout<<r; } // This usage is meaningless, no one would use it like this 

The body of the transformation constructor is determined by the user as needed, so it is important to make it meaningful. For example, the transformation constructor can also be defined as


   Type name ( data )
3


That is, the real part is 0 and the imaginary part is r. It's not against the grammar, but nobody does it. Should conform to the habit, reasonable.

Note: the transformation constructor can take only one argument. If there are multiple arguments, it is not a transformation constructor. The reason is obvious, if there are more than one argument, which argument is converted to an object of class Complex?

In summary, the transformation constructor is used to convert a specified data into a class object as follows:
1) declare a class first.

2) define a constructor with only one parameter in this class, the type of the parameter is the type to be converted, and the method to be converted is specified in the function body.

3) within the scope of this class, you can cast in the following form :
      class name (data of the specified type)
You can convert data of a specified type to an object of this class.
Not only can you convert one standard type of data to a class object, you can also convert the object of another class to the class object on which the transformation constructor resides. If you can convert a student class object into a teacher class object, write the following conversion constructor in the Teacher class:


   Type name ( data )
4


Note, however, that num, name, sex in objects s must be public members or cannot be referenced outside the class.

C++ type conversion function (the type conversion operator function)
A transform constructor is used to convert data of a specified type into an object of a class. However, you cannot convert an object of one class to another type of data (for example, an Complex class object to double type data).

C++ provides a type conversion function (type conversion function) to solve this problem. The cast function converts an object of one class to another type of data. If you have declared an Complex class, you can define the type conversion function in the Complex class like this:


   Type name ( data )
5


The double function returns the value of the type double variable real. It converts an Complex class object into an double type data whose value is the value of real, a data member in the Complex class. Note that the function name is operator double, which is consistent with the rule for operator overloading (operator + when defining an overloaded function for the operator "+").

The general form of the type conversion function is


   Type name ( data )
6


The function type cannot be specified before the function name and the function has no arguments. The type of its return value is determined by the type name specified in the function name. A cast function can only be a member function because the body of the cast is an object of this class. It cannot be a friend function or a normal function.

As you can see from the function form, it is similar to the operator overload function, starting with the keyword operator, except that the type name is overloaded. When the double type is overloaded, it gets a new meaning in addition to its original meaning (an Complex class object is converted to double type data, and the conversion method is specified). In this way, the compilation system can not only recognize the original double data, but also process the Complex class objects as double data.

Then the Complex class pair in the program has the dual identity, which is both the Complex class object and the double type data. The Complex class object is converted only when needed, depending on the context of the expression. The conversion constructor and the type conversion operator have one function in common: the compilation system automatically calls these functions when needed, creating an unnamed temporary object (or temporary variable).

A simple example of using a type conversion function.


#include <iostream>
using namespace std;
class Complex
{
public:
  Complex( ){real=0;imag=0;}
  Complex(double r,double i){real=r;imag=i;}
  operator double( ) {return real;} // Type conversion function 
private:
  double real;
  double imag;
};
int main( )
{
  Complex c1(3,4),c2(5,-10),c3;
  double d;
  d=2.5+c1;// Ask for a double Data and Complex Class data addition 
  cout<<d<<endl;
  return 0;
}

Analysis of the program:
1) if the type conversion function operator double is not defined in the Complex class, the program will compile incorrectly. Because you cannot add double data to Complex class objects. Now that the member function operator double has been defined, you can use it to convert Complex class objects into double type data. Note that there is no need to explicitly call the type converter function in the program; it is called automatically, or implicitly. When do you call a cast function? When the compiler processes the expression 2.5 +cl, it finds that the left side of the operator "+" is double type data, while the right side is Complex type object, and there is no operator "+" overloaded function, which cannot be added directly. The compiler finds that there is an overloaded function of double, so it calls this function, returns an double type data, and then adds it to 2.5.

2) if you add a statement to the main function:


  c3=c2;


Is c2 processed as Complex or as double? Since both sides of the assignment number are the same type of data, it can be assigned legally, so there is no need to convert c2 to double.

3) if the overloaded operator "+" function is declared as a friend function in Complex class:


   Type name ( data )
9


If there is a statement
in the main function


  c3=c1+c2;


Since the operator "+" has been overloaded so that it can be used for the addition of two Complex class objects, c1 and c2 are treated as Complex class objects and assigned to the same class object c3. If I change it to


  d=c1+c2; //d for double Type variable 


Add the two class objects c1 and c2 to get a temporary Complex class object. Since it cannot assign a value to double type variable and there is an overloaded function to double, this function is called to convert the temporary class object to double data and then assign it to d.

From the previous introduction, the concepts and methods of overloading a type and overloading an operator are similar, and overloaded functions use the keyword operator. Therefore, a cast function is often called a cast operator function, and since it is also an overloaded function, it is also called a cast operator overload function (or cast operator overload function).

If the program needs to perform arithmetic operations such as +, -, *, / on an Complex class object and an double type variable, as well as relational and logical operations, if the type conversion function is not used, multiple operators should be overloaded so that various operations can be performed. In this way, it is very troublesome, the workload is larger, the procedure appears lengthy. If you overload double with the type conversion function (converting Complex class objects to double type data), you don't have to overload the various operators, because the Complex class objects can be automatically converted to double type data, and the operations of the standard type data can use the various operators provided by the system.

A program that contains conversion constructors, operator overloading functions, and type conversion functions. Start by reading the following program, which contains only the transform constructor and the operator overload function.


#include <iostream>
using namespace std;
class Complex
{
public:
  Complex( ){real=0;imag=0;} // Default constructor 
  Complex(double r){real=r;imag=0;}// Transformation constructor 
  Complex(double r,double i){real=r;imag=i;}// Implements the initialized constructor 
  friend Complex operator + (Complex c1,Complex c2); // Overloaded operator" + Friend function of" 
  void display( );
private:
  double real;
  double imag;
};
Complex operator + (Complex c1,Complex c2)// Define the operator" + "Overloaded function 
{
  return Complex(c1.real+c2.real, c1.imag+c2.imag);
}
void Complex::display( )
{
  cout<<"("<<real<<","<<imag<<"i)"<<endl;
}
int main( )
{
  Complex c1(3,4),c2(5,-10),c3;
  c3=c1+2.5; // The plural and double Data together 
  c3.display( );
  return 0;
}

Note that when running in an Visual C++ 6.0 environment, the first line needs to be changed to #include < iostream.h > , and delete line 2, otherwise the compilation will not pass.

Analysis of the program:
1) if the transformation constructor is not defined, the program compiles incorrectly.

2) the transformation constructor is now defined in class Complex and specifies how to form a complex number. Since the operator "+" has been overloaded, when the expression c1+2.5 is processed, the compilation system interprets it as


  operator+(c1, 2.5)

Since 2.5 is not an Complex class object, the system first calls the transformation constructor Complex(2.5) to create a temporary Complex class object with a value of (2.5+0i). The function call above is equivalent to


  operator+(c1, Complex(2.5))


Add c1 to (2.5+0i) and assign c3. The result is


  (5.5+4i)


3) if "c3=c1+2.5;" Instead of c3 = 2.5 + c1; Programs can be compiled and run properly. The process is the same as before.

An important conclusion is that when the corresponding transformation constructor is defined, the operator "+" function is overridden as a friend function, and the commutative law can be used when adding two complex Numbers.

If the operator function is overloaded as a member function, its first argument must be an object of the class. Operator functions cannot be overridden as member functions when the first operand is not a class object. Commutative rules do not apply if the operator "+" function is overridden as a member of the class.

For this reason, the binocular operator function is generally overridden as a friend function. Monocular operators are often overloaded as member functions.

4) if you must overload the operator function as a member function, and the first operand is not a class object, there is only one way to solve, and then overload an operator "+" function, its first parameter is double. Of course, this function can only be a friend function, the function prototype is


  friend operator+(double, Complex &);


Obviously this is not very convenient, it is more convenient to overload the binocular operator function as a friend function.

5) add the type conversion function
to the above program


  operator double( ){return real;}


The common part of the Complex class is:


  public:
  Complex( ){real=0;imag=0;}
  Complex(double r){real=r;imag=0;} // Transformation constructor 
  Complex(double r . double i){real=r;imag=i;}
  operator double( ){return real;}// Type conversion function 
  friend Complex operator+ (Complex c1 . Complex c2); // Overloaded operator" + " 
  void display( );

The rest is the same. The program failed at compile time because of ambiguity.


Related articles: