构造函数和析构函数之间的"unexpected"配对。为什么要这样工作?

"unexpected" pairing between constructor and destructor. Why should it work like that?

本文关键字:为什么 工作 配对 析构函数 之间 unexpected 构造函数      更新时间:2023-10-16

代码是我创建的一个测试,以了解确切的工作方式。行为有点出乎意料。如果您知道将显示多少次"创建"answers"已删除",我没有。问题是为什么这样做并且没有不同?

struct A{
    int a=0x10;
     A(){std::cout<<"A created"<<std::endl;}
    ~A(){std::cout<<"A deleted"<<std::endl;}
};
void test0(A a1,A a2){
    std::cout<<"test0"<<" a1="<<a1.a<<" a2="<<a2.a<<std::endl;
}
void test1(const A a1,const A a2){
    std::cout<<"test1"<<" a1="<<a1.a<<" a2="<<a2.a<<std::endl;
}
int main(int argc, char **argv)
{
    A a,b;
    test0(a,b);
    test1(a,b);
}

您误用了构造函数调用。除默认构造函数外,还有对复制构造函数的调用(将A对象传递到您定义的函数中时)。添加复制构造函数的定义显示相等的(默认 复制)构造函数和destructor调用:

#include <iostream>
struct A{
    int a=0x10;
     A(){std::cout<<"A created"<<std::endl;}
     A(const A&) { std::cout << "A copied" << std::endl; } // Copy constructor!
    ~A(){std::cout<<"A deleted"<<std::endl;}
};
void test0(A a1,A a2){
    std::cout<<"test0"<<" a1="<<a1.a<<" a2="<<a2.a<<std::endl;
}
void test1(const A a1,const A a2){
    std::cout<<"test1"<<" a1="<<a1.a<<" a2="<<a2.a<<std::endl;
}
int main()
{
    A a,b;
    test0(a,b);
    test1(a,b);
}

输出:

A created
A created
A copied
A copied
test0 a1=16 a2=16
A deleted
A deleted
A copied
A copied
test1 a1=16 a2=16
A deleted
A deleted
A deleted
A deleted

实例示例

编译器将提供复制构造函数的默认实现(如果您自己不定义一个),该实现是对成员字段的微不足道的副本。当您将A对象传递到功能中时,正在使用该默认实现,并在功能主体内构造本地副本。您看到的额外的驱动器呼叫来自这些副本。如果您定义自己的复制构造函数,则可以在调用消息时打印一条消息,并且总计现在按预期匹配。