Problems with C + + returning objects (temporary object issues)

Source: Internet
Author: User

Conclusion:

(1) If a method of a class returns an object (a class object), this object should be assigned first to a local variable in use before the local variable is used. It is not possible to invoke the other with this temporary variable as an intermediate variable.

1, a detailed question about the use of qstring::tostdstring ()

Example:

"Hello, world!"; char *cstr = str.tostdstring (). C_STR (); //2, correct usage std::string sstr = Str.tostdstring ();  Char *cstr2 = SSTR.C_STR (); //3,       the right usage
Func (Str.tostdstring (). C_STR ());

The reasons are as follows:
  

To explain the difference between the first two pieces of code execution, we need to check QString::toStdString() the signature:

std::const;

This function returns an object that QString is identical to this content std::string . Note that the return value of this function is an object . In C + +, the function return object is generally similar to the following code:

const{    clazz C;    0;    return c;} 

Note that the return object here is actually a temporary object. In the code above, although we created an object in the body clazz of the function c , but returned not the "this" object, but instead created a temporary object by C + +, and then returned the temporary object. Note that this is a "temporary object", and the temporary object is life-cycle. In the 10th chapter of the C + + programming language, " unless a temporary object is constrained to a reference or used as the initialization of a named object, it will be destroyed at the end of the complete expression that created it ." A "complete expression" is an expression that is not a sub-expression of another expression. In simple terms, the identity of a complete expression is generally a semicolon.

This seemingly winding phrase explains all the previous phenomena. In the first code, because the function returns a temporary variable, we immediately call the function of the temporary object c_str() . None of this is a problem. After that, the complete expression ends (a semicolon is encountered), and the temporary variable is not assigned to a reference or used to initialize an object, so the temporary variable is immediately destroyed. The result of the function obtained by this object c_str() is also destroyed, so a segment error occurs.

In the second piece of code, this temporary variable is used to sstr initialize the object, and then we call the function of the new initialized object, which is normal.

The third code, although not assigned to a reference or used to initialize an object, does not end at the end of the statement, but str.toStdString().c_str() continues to execute the function call. The temporary variable is not destroyed until the function call returns and encounters a semicolon that represents the end of the expression. At this point we have successfully executed the function code. So everything is fine.

At this point, we understand that this seemingly strange phenomenon is actually a C + + language trap, and even has nothing to do with Qt. Similar traps can also occur on QString::toUtf8() QString::toAscii() functions such as, and the like.

10.4.10 Temporary objects

Temporary objects often appear as the result of arithmetic expressions. If the intermediate result of the evaluation X*y+z X*y is a temporary object, there must be somewhere.

Unless a temporary object is constrained to a reference or used to initialize a named object, it will always be destroyed at the end of the complete expression that established it. A complete expression is an expression that is not a sub-expression of another expression. Consider the following function, which is a common mistake.

void F (string& s1, string& S2, string& S3)

{Const CHAR* CS = (s1+s2). C_STR ();//After the completion of the full expression assignment, the temporary variable is destroyed and CS becomes the wild pointer! cout << CS; Error!

if (strlen (cs = (S2+S3). C_STR ()) < 8 && Cs[0] = = ' a ')
{
cout << CS; Error, Reason ibid.
 
}
}

In order to avoid such errors we can use the following method.

void G (string& s1, string& S2, string& S3)

{
cout << (S1+S2). C_STR (); The temporary object is destroyed at the end of the full expression cout, so cout can be output correctly.
string s = s2 + s3;
if (S.length () < 8 && S[0] = = ' a ')  

{
cout << S;
}
}

You can also use a temporary variable as a const reference or as an initializer for a named object, for example,
void H (string& s1, string& S2)

{
Const string& s = s1 + s2;
string ss = S1 + s2;
G (S, SS, S1);
}

Such a temporary variable is pin when his reference or named variable leaves scope. Destroy. Therefore, the temporary variable is an anonymous local variable, and it is wrong to return a reference to the local variable. A temporary variable is not an lvalue variable and cannot be constrained to a non-cosnt reference.

Problems with C + + returning objects (temporary object issues)

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.