C ++ temporary object Source

Source: Internet
Author: User

First, let's look at the following code:

Copy codeThe Code is as follows: # include <iostream>
Void swap (int & a, int & B)
{
Int temp;
Temp =;
A = B;
B = temp;
}

Int main (int argc, char ** argv)
{
Int a = 1, B = 2;
Swap (a, B );
Std: cout <a <"-----" <B <std: endl;
Return 0;
}

Result:
2-----1
Most park friends may think that "int temp" is a "temporary object", but in fact it is not, "int temp" is only a local variable of the swap function.

Temporary objects cannot be seen in the code, but they do exist in the actual program. Temporary objects can be perceived by the compiler.

Why study temporary objects?
The main purpose is to improve the performance and efficiency of the program. Because the Construction and Analysis of temporary objects are not small for the system overhead, we should understand them and know how they cause them, avoid them as much as possible.

Creating a non-heap object without naming a temporary object will generate a temporary object. (I don't know what heap objects and non-heap objects are. For details, refer to the blog article C ++ which you 'd better not do. This article will introduce them here .) This unnamed object is usually generated under three conditions: implicit type conversion for successful function calls, function parameters passing, and function return objects.

First, let's take a look at the implicit type conversion to make the function call successful.

Copy codeThe Code is as follows: # include <iostream>
Int countChar (const std: string & s, const char c)
{
Int count = 0;
For (int I = 0; I <s. length (); I ++)
{
If (* (s. c_str () + I) = c)
{
Count ++;
}
}
Return count;
}

Int main (int argc, char ** argv)
{
Char buffer [200];
Char c;
Std: cout <"please input the string :";
Std: cin> buffer;
Std: cout <"please input the char which you want to chount :";
Std: cin> c;
Int count = countChar (buffer, c );
Std: count <"the count is:" <count <std: endl;
Return 0;
}

Result:

The countChar (const std: string & s, const char & c) function is called here. Let's take a look at the form parameter of this function as const std: string & s, the parameter type is const std: string, but the array char buffer [200] is actually passed. In fact, the compiler converts the char * type to the std: string type to make the function call a successful type conversion. This conversion is performed by a value assignment constructor, use buffer as a parameter to construct a temporary object of the std: string type. When constChar is returned, that is, the function is revoked, the std: string temporary object is released. But in fact, the construction and release of temporary objects are unnecessary overhead for the whole program. We can improve the code efficiency and modify the code to avoid unnecessary conversions. So knowing the source of the temporary object can greatly improve the program performance.

Note that this type of conversion occurs only when an object is passed by passing the value or a constant reference parameter. This type of conversion does not occur when a parameter object with a very large amount of reference is passed. Because the intention to pass a very large number of referenced parameters is to change the value of the passed parameter through the function, but the function is actually a temporary object created by the type conversion, so the intent cannot be implemented, the compiler simply rejects the request.

The second case is that when you are familiar with function parameters, a temporary object is constructed. The running result of the following code is clear.

Copy codeThe Code is as follows: # include <iostream>
Class People
{
Public:
People (std: string n, int)
: Name (n), age ()
{
Std: count <"h2" <std: endl;
}
People ()
{
Std: count <"h1" <std: endl;
}
People (const People & P)
{
Name = p. name;
Age = p. age;
Std: cout <"h3" <std: endl;
}
Std: string name;
Int age;
};

Void swap (People p1, People p2)
{
People temp;
Temp. age = p1.age;
Temp. name = p1.name;
P1.age = p2.age;
P1.name = p2.name;
P2.age = temp. age;
P2.name = temp. name;
}

Int main (int argc, char ** argv)
{
People p1 ("tom", 18), p2 ("sam", 19 );
Swap (p1, p2 );
Return 0;
}

Result:

The preceding two "h2" are printed by calling the constructor People (std: string n, int, while "h3" is printed by calling the replication constructor People (const People &) and creating a temporary object. h1 is printed by calling the default constructor People. So how can we avoid creating temporary objects? It's easy. We can reference real parameters to achieve our goal.

Void swap (People & p1, People & p2)
The third scenario is when the function returns an object. Note that temporary objects are created by using the copy constructor.

For example, const Rationanl operator + (Rationanl a, Rationanl B) temporarily returns the value of this function because it is not named and it is only the return value of the function. Each time you call add, you must pay the price to construct and release this object.

Copy codeThe Code is as follows: # include <iostream>
Class Rationanl
{
Public:
Rationanl (int e, int d)
: _ Elemem (e), _ denom (d)
{
Std: cout <"h2" <std: endl;
}
Void show () const;
Int elemem () const {return _ elemem ;}
Int denom () const {return _ denom ;}
Void setElemon (int e) {_ elemon = e ;}
Void setDenom (int d) {_ denom = d ;}
Rationanl (const Rationanl & r );
Rationanl & operator = (const Rationanl & r );
Private:
Int _ elemem;
Int _ denom;
};
Rationanl: Rationanl (const Rationanl & r)
{
SetElemon (r. elemon ());
SetDenom (r. denom ());
Std: cout <"h3" <std: endl;
}
Rationanl & Rationanl: operator = (const Rationanl & r)
{
SetElemon (r. elemon ());
SetDenom (r. denom ());
Std: cout <"h4" <std: endl;
Return * this;
}

Void Rationanl: show ()
{
Std: cout <_ elemen <"/" <_ denom <std: endl;
}
Const Rationanl operator * (const Rationanl lhs, const Rationanl rhs)
{
Return Rational result (lhs. elemen * rhs. elemen, rhs. denom * rhs. denom );
}

Int main (int argc, char ** argv)
{
Rationanl r1 (1, 2), r2 (1, 3)
Rationanl r3 = r1 * r2; // GCC is optimized and no temporary variables are displayed. The compiler directly skips the establishment of r3 and uses the value assignment symbol.
R3.show ();
// Equivalent to (r1 * r2). show ();
Return 0;
}

Result:

It is a pity that we didn't see the expected results. The results should be h2, h2, h2, h3, h4. There should be a value assignment constructor in the return value, after creating a temporary variable, the author found information on the Internet and confirmed that GCC was optimized.

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.