【问题标题】:Why destructors are called when passing to a function but not constructors? [duplicate]为什么在传递给函数而不是构造函数时调用析构函数? [复制]
【发布时间】:2020-09-06 12:07:25
【问题描述】:

让我们看看这段代码。为什么调用的析构函数的数量比构造函数的多?

#include <iostream>
using namespace std;


class B{

    public:
    B(){
        cout << "constructor of B\n";
    }
    ~B(){
        cout << "destructor of B\n";
    }
};


void func(B obj){
}


int main(){
    B obj;
    func(obj);
}

输出是

constructor of B
destructor of B
destructor of B

不明白为什么调用的析构函数的数量和调用的构造函数的数量不一样?

【问题讨论】:

  • 您没有跟踪复制构造函数的数量。如果您打印出this 的值以及这些消息,您会发现缺少某些内容。
  • 如果您使用gdb 调试程序,当您进入func(obj); 时,您将看到一个您从未声明被调用的函数:B::B(const B&amp;)。见implicitly defined copy-constructor
  • 规则 0:每个构造函数调用都匹配一个析构函数调用,每一个析构函数调用匹配一个构造函数调用。 (除非你使用 new 和 delete 并搞砸了)

标签: c++ oop constructor destructor


【解决方案1】:

您正在将对象按值传递给函数。因此,制作对象的副本导致调用对象的复制构造函数。当函数结束执行时,参数的临时副本被销毁,调用析构函数。

【讨论】:

    【解决方案2】:

    只需更改函数func() 的签名将帮助您了解真正缺少的东西。考虑一下这个:

    void func(B & obj) { ... }
    

    在这里,您将通过引用传递对象,并且您将不再收到两个析构函数消息,因为直接操作类函数并且不会调用临时复制的参数。

    然后你应该得到类似这样的输出:

    construct of B
    destructor of B
    

    【讨论】:

    • 嗯,不,他们现在正在调用复制构造函数,如果他们切换到引用,他们就不会......
    • OP 将无法理解为什么通过更改代码以使 desctuctor 按预期调用而超出预期调用 desctuctor 的原因。你并没有真正回答这个问题
    • @idclev463035818 我希望他能通过阅读问题中突出显示的评论来理解它。所以我只是试着回答。
    猜你喜欢
    • 2015-06-10
    • 2012-06-28
    • 1970-01-01
    • 2013-04-25
    • 2017-09-04
    • 2012-04-29
    • 2018-01-20
    • 2019-11-07
    相关资源
    最近更新 更多