C + + Assorted: The return value of my home can not be so proud (right value reference and mobile semantics) __c++

Source: Internet
Author: User
Generally speaking programming language, there will be "function" this concept. For the outside, the most important part of a function is its return value.

Say here, the return value should actually be a very simple topic. When you need to pass a value through a function to go out, using the return value is not taken for granted, for example, like the following:

int add (int a, int b)
{return
    a + b;
}

int main (int argc, char* argv[])
{
    int i = Add (1, 2);
    Std::cout << i << Std::endl;
    return 0;
}

Return the result of the function directly by return value, whether the function or the caller will be happy, because this is the most natural way to use. But in C + +, returning the processing result through the function return value is often a luxurious behavior.

first, use the return value of the problem , for example, this wording:

int main (int argc, char* argv[])
{
    std::string ss;
    std::string S1 ("Hello"), S2 ("-"), S3 ("World"), S4 ("!");
    SS = S1 + s2 + s3 + S4;
    Std::cout << SS << Std::endl;
    return 0;
}

I believe that experienced C + + programmers will frown, good practice should be to use + + instead:

int main (int argc, char* argv[])
{
    std::string ss;
    std::string S1 ("Hello"), S2 ("-"), S3 ("World"), S4 ("!");
    SS = S1 + + s2 + = s3 + = S4;
    Std::cout << SS << Std::endl;
    return 0;
}

The reason for this is simple: the implementations of + and + + operator overloading are generally like this.

operator char* (void) const
{return
    str_;
}

str& operator+= (const char* str)
{
    if (str) strcat_s (STR_, 1024, str);
    return (*this);
}

Friend Str operator+ (const str& x, const str& y)
{return
    str (x) = y;
}

Note that line 14th of the above code, since the + operator cannot modify any one of the parameters, must construct a temporary variable, str (x), and STR (x) immediately destroys the value after passing it out. The outside responsible for the received variable can only be obtained and copied over str (x), so a simple return value causes a copy of two times x. When added like "ss = S1 + s2 + s3 + S4" above, the copy will take place at each + call, like a drum pass.

We cannot replace the value of + with a reference or a pointer as = =, since str (x) is naturally destroyed after the operator+ scope, and the external reference will be a dangling reference, which cannot be used to get the processed data.

To illustrate the problem, we can write a simple example to see how much of a loss this assignment will be:

Class Str {protected:char* str_;            Public:str (void)//default constructor, do nothing: Str_ (nullptr) {} Str (const char* RHS)
        Normal assignment constructor: Str_ (nullptr) {if (!RHS) return;
        Str_ = new char[1024];
        strcpy_s (STR_, 1024, RHS);
    Std::cout << "Str constructor" << str_ << Std::endl;
        } Str (const str& RHS)//copy constructor: Str_ (nullptr) {if (!RHS) return;
        Str_ = new char[1024];
        strcpy_s (STR_, 1024, rhs.str_);
    Std::cout << "Str copy constructor" << str_ << Std::endl;
        ~STR ()//destructor {if (!str_) return;
        Std::cout << "Str destructor" << str_ << Std::endl;
    delete [] str_;            Const str& operator= (STR RHS)//assignment operator overload {Rhs.swap (*this);            Data return (*this) is obtained by using the Copy-and-swap idiom; Avoid repeating operator=} void Swap (str& RHS)//Exchange algorithm {Std::swap (str_, rhs.str_);
    } operator char* (void) const {return str_;
        } str& operator+= (const char* RHS) {if (RHS) strcat_s (STR_, 1024, RHS);
    return (*this);
    Friend Str operator+ (const str& x, const str& y) {return str (x) = y;

}
};
    int main (int argc, char* argv[]) {Str ss;
    Str S1 ("Hello"), S2 ("-"), S3 ("World"), S4 ("!");

    Std::cout << Std::endl;

    SS = S1 + s2 + s3 + S4;
    Std::cout << Std::endl;
    Std::cout << SS << Std::endl;
    Std::cout << Std::endl;
return 0; }

This is a simple STR class that wraps up a char* and restricts the string length to 1024.

After the program is run, we get the following print information:

Str copy Constructor Hello
Str copy Constructor hello-
Str destructor hello-
Str copy Constructor hello-
Str copy Constructor Hello-world
Str destructor Hello-world
Str copy Constructor Hello-world
Str copy Constructor hello-world!
Str destructor hello-world!
Str destructor Hello-world
Str destructor hello-

This one.. It's beautiful. 6 consecutive copies of the structure, and eventually these temporary generated strings all blown off like a crackling was destroyed.
A copy of the work is new a 1024 of the large memory block, another strcpy. Continuous construction-copy-destructor can have a significant impact on performance.
So try to choose + is actually a last resort to things.

In the same way, we rarely write Str inttostr (int i) and replace it with void inttostr (int i, str& s).
To avoid performance problems with return values, the C++er had to sacrifice the elegance of the Code and solve it with lame arguments.

Second, some solutions

Unworthy is not the way, as a programmer (not just C + + programmers), the pursuit of efficiency is understandable, but can not tolerate language restrictions on our productivity, imprison our thoughts.

One workaround is to use Cow (copy-on-write). We can not copy the data every time, only when the data is overwritten, the copy operation will appear.
In the code, in the copy constructor of Str above, the strcpy is no longer used directly, instead of a short copy of a line of pointer duplication (note that is not a copy of the content). Until + = This will change the content of the operation, STR internal will create another memory, and copy the existing data once.

The cost of doing so is:

1. We need to use "reference count" to mark the current block of memory by how many Str are common, otherwise a str deletes memory in the destructor, and all the pointers within the other STR classes associated with it become wild pointers. 2. We need to deal with all cow triggering mechanisms, that is, to distinguish when STR is being written. The benefits are:

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.