C++ 何时自动调用析构函数?

C++ 何时自动调用析构函数?,c++,C++,我正在玩析构函数和operator=,输出对我来说很奇怪 两个版本的主要功能: int main() { B b1; B b2; b2=b1; cout<<"---"<<endl; return 0; } 现在操作符=returnB&而不是B,输出不一样;析构函数调用两次,而不是以前的三次。为什么? B类 { 公众: B&B操作员=(B&b1) { cout代码工作正常,如预期。在第一种情况下,在“operator=”之后调用析

我正在玩
析构函数
operator=
,输出对我来说很奇怪

两个版本的主要功能:

int main()
{
    B b1;
    B b2;
    b2=b1;
    cout<<"---"<<endl;
    return 0;
}
  • 现在操作符=return
    B&
    而不是
    B
    ,输出不一样;析构函数调用两次,而不是以前的三次。为什么?
  • 
    B类
    {
    公众:
    B&B操作员=(B&b1)
    {
    
    cout代码工作正常,如预期。在第一种情况下,在“operator=”之后调用析构函数,因为您返回的是B:

    B operator=(B& b1)
    {
        cout<<"operator="<<endl;
        return b1;
    }
    
    但是,在第二种情况下,赋值运算符重载的返回类型为B&,复制构造函数将永远不会被调用,因为它将返回对它接收的对象的引用,而不是副本。因此,对于在main()方法中创建的对象b1和b2,析构函数只会被调用两次。
    希望这能回答您的问题。

    在第一种情况下,您还有一个实例:

    int main()
    {
        B b1;
        B b2;
        b2=b1;               <---- here b2.operator=(b1) returns another B instance 
                                   (its a copy of b1)
        cout<<"---"<<endl;
        return 0;
    }
    
    使实例在作用域结束前保持活动状态。在这种情况下,您将看到在打印
    --
    后调用析构函数


    还要注意的是,两个操作符都不正确,因为操作符应该返回对
    *this
    的引用,而不是对其他实例的引用。(PaulMcKenzie在评论中已经提到过,请在此处重复,以确保不会丢失)

    因为在一种情况下,您的
    操作符=
    返回一个新创建的实例(它不应该返回),而在另一种情况下它不返回。这不是很明显吗?顺便说一句“这不是很明显吗?”这并不意味着冒犯,只是试图理解您丢失了什么两个函数都写得不正确,因为
    操作符=
    应该返回对当前对象的引用,而不是一个全新的对象,也不是对另一个对象的引用。您知道这在引擎盖下到底做了什么吗??:b2=b1;@tobi303 I sti我不明白为什么在第二种情况下,析构函数没有被调用。@PaulMcKenzie你的意思是我应该为
    操作符=
    的每次调用在堆上分配内存,这样我就可以返回他的引用了吗?@ΦXocę웃 Пepeúpaツ 因为您返回的是B对象的本地副本:“没有本地副本,否则将调用析构函数两次(一次用于本地,一次用于主实例中返回的实例)。是的,因为第一种情况下的返回类型(理想情况下不应该是这样的)。您显式地告诉函数返回“B”而不是“B&”,因此它调用复制构造函数并返回实例而不是引用。是的,但是
    操作符=
    中没有本地副本。同意,我实际上不应该将其称为“本地副本”。
    B operator=(B& b1)
    {
        cout<<"operator="<<endl;
        return b1;
    }
    
    class B
    {
        public:
            B operator=(B& b1)
            {
                cout<<"operator="<<endl;
                return b1;
            }
            ~B()
            {
                cout<<"destructor"<<endl;
            }
    
            B(const B& b1){
                cout << "Copy constructor called" << endl;   
            }
    
            B(){}
    };
    
    operator=
    Copy constructor called
    destructor
    ---
    destructor
    destructor
    
    int main()
    {
        B b1;
        B b2;
        b2=b1;               <---- here b2.operator=(b1) returns another B instance 
                                   (its a copy of b1)
        cout<<"---"<<endl;
        return 0;
    }
    
       B b3 = (b2=b1);