通过函数的值和隐含的移动规则返回命名对象
考虑通过以下方式返回泛型类的对象的情况来自函数的值。在示例 1 中:
<code class="cpp">class test { public: test() { printf(" test()\n"); } test(test&& s) { printf(" test(test&& s)\n"); } test& operator=(test e) { printf(" test& operator=( test e)\n"); return *this; } }; test Some_thing() { test i; return i; }</code>
输出为:
test() test(test&& s)
在此示例中,为我在函数中创建的 LValue 对象调用构造函数 test(),并且移动当通过值返回对象 i 时,会调用构造函数 test(test&& s),因为表达式 return i 是右值引用。
在示例 2 中,提供了复制构造函数 test(test& z),但是编译器不会合成移动构造函数:
<code class="cpp">class test { public: test() { printf(" test()\n"); } test(test& z) { printf(" test(test& z)\n"); } test& operator=(test e) { printf(" test& operator=( test e)\n"); return *this; } }; test Some_thing() { test i; return i; }</code>
输出与示例 1 相同:
test() test(test& z)
使用复制构造函数,因为没有可用的移动构造函数。
在示例 3 中,移动构造函数被显式删除:
<code class="cpp">class test { public: test(test&& z) = delete; // Deleted move constructor test() { printf(" test()\n"); } test(test& z) { printf(" test(test& z)\n"); } test& operator=(test e) { printf(" test& operator=( test e)\n"); return *this; } }; test Some_thing() { test i; return i; }</code>
尝试编译此代码将导致错误,因为删除的移动构造函数意味着无法执行移动操作.
在示例 4 中,即使删除了移动构造函数,代码也会编译并运行:
<code class="cpp">class test { public: test(test&& z) = delete; test() { printf(" test()\n"); } test(test& z) { printf(" test(test& z)\n"); } test& operator=(test e) { printf(" test& operator=( test e)\n"); return *this; } }; int main() { test u; test r(u); // Copy constructor is used return 0; }</code>
输出:
test() test(test& z)
在此示例中, r (u) 通过复制对象 u 创建一个新对象 r。移动构造函数没有被使用,因为它被删除了,而是使用了复制构造函数。
关键的一点是,是否使用移动构造函数取决于可行的移动构造函数的可用性以及以下规则:过载决议。如果移动构造函数可用且可行,则它可以用于初始化函数的返回值,即使用于返回值的表达式是 LValue。
以上是C 中什么时候使用 Move 构造函数按值返回命名对象?的详细内容。更多信息请关注PHP中文网其他相关文章!