"If a worker wants to do his job well, he must first sharpen his tools." - Confucius, "The Analects of Confucius. Lu Linggong"
Front page > Programming > When Does Returning an Object by Value Trigger a Move Constructor?

When Does Returning an Object by Value Trigger a Move Constructor?

Published on 2024-11-16
Browse:115

When Does Returning an Object by Value Trigger a Move Constructor?

Returning an Object of a Class from a Function by Value

Consider the case where you return an object of a class from a function by value. In this scenario, the returned object is typically considered an lvalue, meaning it has a name and an address in memory. However, certain circumstances can result in the returned object being treated as an rvalue, a temporary object without a name or address.

The Implicit Move Rule

C defines an implicit move rule that may apply when returning an object by value. This rule states that if the following conditions are met:

  • The returned expression is an xvalue (an expression denoting a temporary object that is not an lvalue).
  • The class of the returned object has a move constructor.
  • The move constructor is accessible.

In such cases, the move constructor will be invoked instead of the copy constructor. This behavior is intended to optimize performance by avoiding unnecessary copying.

Example 1

In this example, the returned object i is an lvalue, so the copy constructor test(const test& z) is invoked:

class test {
public:
    test(int y) { printf("test(int y)\n"); }
    test() { printf("test()\n"); }
    test(const test& z) { printf("test(const test&z)\n"); }
};
test Some_thing() {
    test i;
    return i;
}

Output:

test()
test(const test&z)

Example 2

However, in the following example, the returned object i is treated as an xvalue, and the move constructor test(test&& s) is invoked because the object is temporary and the move constructor is viable:

class test {
public:
    test(int y) { printf("test(int y)\n"); }
    test() { printf("test()\n"); }
    test(test&& s) { printf("test(test&& s)\n"); }
};
test Some_thing() {
    test i;
    return i;
}

Output:

test()
test(test&& s)

Example 3

If a move constructor is not provided or is explicitly deleted, the implicit move rule cannot be applied, and the program will fail to compile:

class test {
public:
    test(test&& z) = delete;
    test(int y) { printf("test(int y)\n"); }
    test() { printf("test()\n"); }
    test(const test& z) { printf("test(const test&z)\n"); }
};
test Some_thing() {
    test i;
    return i;
}

Conclusion

When returning an object by value, the implicit move rule may be applied under specific conditions, resulting in the move constructor being invoked. Understanding this behavior is crucial for optimizing code and preventing compilation errors.

Latest tutorial More>

Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.

Copyright© 2022 湘ICP备2022001581号-3