gpt4 book ai didi

c++ - 复制构造函数并返回传递的参数

转载 作者:太空宇宙 更新时间:2023-11-04 14:29:16 26 4
gpt4 key购买 nike

我正在阅读 Prata 的 C++ 书,在谈到复制构造函数时,它说在以下情况下调用此构造函数:

  1. 将类对象初始化为相同类型的类对象。
  2. 按值将对象传递给函数。
  3. 从函数中按值返回对象。

假设我们正在使用一个 Vector 类。

为了便于理解,在当前章节的所有示例中,我们都在构造函数/析构函数定义字符串输出中包含了字符串输出,以指示调用它们中的每一个以及何时调用它们。

例如,如果我们有

int main()
{

Vector v1; // print "Default constructor called"
Vector v2(9, 5); // print "Constructor called"
Vector v3 = v1; // print "Copy Constructor called"

return 0;
}

在这种情况下,Destructor called 会在退出 main() 时打印 3 次。


为了检查以上 3 点,我一直在玩 dumb_display() 函数,更改形式参数/返回值的类型。在这样做的过程中,我对幕后发生的事情感到困惑。

Vector dumb_display(Vector v)
{
Vector test(45, 67);
cout << "In dumb_display() function" << endl;
cout << v << endl;
return v;
}

这里:

  • 每次我们像上面的函数一样按值返回传递的参数(按值或引用传递的参数)时,复制构造函数都会被调用。

    • 很有道理。它满足第 3 点。

每次我们返回在函数体中定义的对象(例如,将 return v; 更改为 return test;),都不会调用复制构造函数。

  • 不满足第 3 点。

我很难理解这种行为。

我不知道这是否正确,但我认为(因为在函数调用期间创建了一次自动存储持续时间对象)一旦 test 创建了它,还没有必须重新创建,因为对象“已经存在”。这就带来了问题:

为什么返回传递的参数会调用两次拷贝构造函数?为什么在函数调用期间必须创建两次相同的对象?

最佳答案

#include <vector>
#include <type_traits>
#include <tuple>
#include <iostream>

using namespace std;

struct S {
S(){
cout << "default constructor" << endl;
}
S(S const &) {
cout << "copy constructor" << endl;
}
S(S &&) {
cout << "move constructor" << endl;
}
S & operator=(S const &) {
cout << "copy assignment" << endl;
return *this;
}
S & operator=(S &&) {
cout << "move assignment" << endl;
return *this;
}
};

S f() {
S s2;
cout << "In f()" << endl;
return s2;
}

S f2(S s) {
cout << "In f2()" << endl;
return s;
}

int main() {
cout << "about to call f" << endl;
S s2 = f();
(void)s2;

cout << endl << "about to call f2" << endl;
S s3 = f2(s2);
(void)s3;
}

结果:

about to call f
default constructor
In f()

about to call f2
copy constructor
In f2()
move constructor

f() 中,对象是默认构造的,返回值优化用于在实际结束的地方实际构造它——在 main 中的 s2 变量中。没有调用复制/移动构造函数。

f2() 中,为函数的输入参数制作了一个拷贝。然后将该值移入 main 中的变量 s3,再次进行返回值优化。

直播:https://wandbox.org/permlink/kvBHBJytaIuPj0YN

如果您关闭返回值优化,您将看到书中所说的结果:

直播:https://wandbox.org/permlink/BaysuTYJjlJmMGf6

如果您感到困惑,这里有两个没有 move 运算符的相同示例:

直播:https://wandbox.org/permlink/c0brlus92psJtTCf

并且没有返回值优化:

直播:https://wandbox.org/permlink/XSMaBnKTz2aZwgOm

它是相同数量的构造函数调用,只是使用(可能更慢)复制构造函数而不是移动构造函数。

关于c++ - 复制构造函数并返回传递的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49507989/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com