Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么我的析构函数被调用了两次?_C++_Destructor - Fatal编程技术网

C++ 为什么我的析构函数被调用了两次?

C++ 为什么我的析构函数被调用了两次?,c++,destructor,C++,Destructor,假设我有一个班上的学生,使用以下方法: Student Student::method(Student x) { //nothing important return x; } 复制构造函数被调用两次,一次是当对象x作为参数发送时,第二次是当x从函数返回时 当我调用这个方法时,为什么要调用两次类学生的析构函数? 调用是这样的:a=b.method(c),其中a、b和c是学生对象。如果构造了两个学生对象,则必须对它们进行解构。输入参数和输出返回值的副本需要销毁。如果构造了两个学生

假设我有一个班上的学生,使用以下方法:

Student Student::method(Student x)
{
    //nothing important
    return x;
}
复制构造函数被调用两次,一次是当对象x作为参数发送时,第二次是当x从函数返回时

当我调用这个方法时,为什么要调用两次类学生的析构函数?
调用是这样的:a=b.method(c),其中a、b和c是学生对象。

如果构造了两个学生对象,则必须对它们进行解构。输入参数和输出返回值的副本需要销毁。

如果构造了两个学生对象,则必须销毁它们。输入参数和输出返回值的副本需要销毁。

当函数返回时(将
x
复制到返回值后),调用
x
的析构函数

在包含函数调用的完整表达式末尾调用返回值的析构函数(除非通过将返回值分配给引用来延长其生存期)


构造的每个具有自动存储持续时间的对象都将自动销毁(通常与构造顺序相反)。您构造了两个对象(
x
和返回值),因此有两个析构函数调用。

当函数返回时(将
x
复制到返回值后),将调用
x
的析构函数

在包含函数调用的完整表达式末尾调用返回值的析构函数(除非通过将返回值分配给引用来延长其生存期)


构造的每个具有自动存储持续时间的对象都将自动销毁(通常与构造顺序相反)。构造两个对象(
x
和返回值),因此有两个析构函数调用。

例如,
a=b.method(c),有三个副本可能发生,为避免副本省略而保存。第一个是当
c
对象被复制到函数参数
x
中时。第二个是当函数返回
x
对象时。第三个是将返回值复制到
对象中时。前两个涉及复制构造函数,最后一个涉及复制赋值操作符,除非您将其更改为
Student a=b.method(c),在这种情况下,它们都使用复制构造函数

a
b
c
都将在其范围结束时销毁。对象
x
将在
方法
函数结束时销毁。函数的返回值将在包含它的完整表达式的末尾被销毁-也就是说,一旦
a=b.method(c)已完成


但是,并非所有这些副本都必须出现-在某些情况下,编译器可以省略或省略类的复制/移动构造。将第一次复制到函数参数中。在尝试复制之前,函数的第二次复制将被视为先移动。此复制或移动可以省略。如果您使用复制赋值,将出现从临时返回值到
a
的最终复制,但如果您使用复制构造函数(如
Student a=b.method(c);
)。

例如,
a=b.method(c),有三个副本可能发生,为避免副本省略而保存。第一个是当
c
对象被复制到函数参数
x
中时。第二个是当函数返回
x
对象时。第三个是将返回值复制到
对象中时。前两个涉及复制构造函数,最后一个涉及复制赋值操作符,除非您将其更改为
Student a=b.method(c),在这种情况下,它们都使用复制构造函数

a
b
c
都将在其范围结束时销毁。对象
x
将在
方法
函数结束时销毁。函数的返回值将在包含它的完整表达式的末尾被销毁-也就是说,一旦
a=b.method(c)已完成


但是,并非所有这些副本都必须出现-在某些情况下,编译器可以省略或省略类的复制/移动构造。将第一次复制到函数参数中。在尝试复制之前,函数的第二次复制将被视为先移动。此复制或移动可以省略。如果您使用复制赋值,将出现从临时返回值到
a
的最终副本,但如果您使用复制构造函数(如
学生a=b.method(c);
),则可能会忽略该副本。

是关于构造函数还是析构函数的问题?标题说的是一件事,问题的主体是另一件事。这个问题是关于构造函数还是析构函数的?标题说的是一件事,问题主体说的是另一件事。那么在我将b.method(c)返回的对象分配给a的那一行之后,这个对象被销毁了吗?这和=,对吗?@Sorin:对。在某些情况下,“复制省略”是唯一一个变得棘手的部分,例如
Student a(b.method(c))
可以(也可以不,未指定)直接在
a
对象中构造返回值,从而延长返回值的生存期。同样
学生常数&a(b.方法(c))
将(肯定地)将返回值的生存期延长到
a
引用的范围。因此,在我将b.method(c)返回的对象分配给a的行之后,该对象被销毁了吗?这和=,对吗?@Sorin:对。在某些情况下,“复制省略”是唯一一个变得棘手的部分,例如
Student a(b.method(c))