当我调用一个简单的函数时,析构函数被调用

时间:2016-01-11 09:51:15

标签: c++ c++14

我做了一个简单的程序制作一个类,它是3个对象。我重载了=,+ =和<<运营商。问题是当我使用=和+ =运算符时,在执行函数后会调用析构函数。

据我所知,当一个对象超出范围或者删除'时,会调用析构函数。使用运算符。但是,就我而言,这两者都不是。我查看了其他一些网站,例如the oficial C++ website,但是,我无法得到答案。这是我写的代码。

#include<iostream>
using namespace std;

class Class
{
    int flag,name;
public:
    Class(int y,int z)
{
    flag=y;
    name=z;
}

    Class& operator=(Class);
    Class operator+=(Class);
    friend ostream& operator<<(ostream&,Class&);    

    ~Class()
{
    cout<<"Destroying "<<flag<<endl;
}
};

int main()
{
    Class C1(1,80),C2(2,90),C3(3,100);
    cout<<C1<<C2<<C3<<endl;
    C1=C2=C3;
    cout<<C1<<C2<<C3<<endl;
    C3=C1+=C2;
    cout<<C1<<C2<<C3<<endl;
    return 0;
}

Class& Class::operator=(Class x)
{
    name=x.name;
    return *this;
}

Class Class::operator+=(Class x)
{
    name+=x.name;
    return *this;
}

ostream& operator<<(ostream& o,Class& c)
{
    o<<c.name;
    return o;
}

我得到的输出是:

8090100
Destroying 2
Destroying 3
100100100
Destroying 1
Destroying 2
200100200
Destroying 3
Destroying 2
Destroying 1

C2,C3和C1,C2的析构函数在此过程中被调用,即使它们不在范围之外。我通过更改函数名称甚至将返回类型更改为&#39; void&#39;来尝试此程序,但仍然会调用析构函数。我在GCC-4.9.3中编译了这个程序。

我很感激这个主题的任何帮助,如果我的问题太愚蠢,请原谅我。

3 个答案:

答案 0 :(得分:10)

您的操作符按值获取参数,制作一个在函数结束时将被销毁的副本。

如果您不想创建副本,请通过const引用获取参数。正如interjay所指出的那样,operator+=也应该返回引用而不是复制*this

Class& operator=(const Class&);
Class& operator+=(const Class&);

答案 1 :(得分:3)

Class& Class::operator=(Class x);

C1=C2=C3;

当您C2 = C3注意到operator=按值右侧时,会创建C3的副本(x);其数据已复制到C2。当函数operator=返回时,参数x超出范围并被销毁。这种情况发生了两次:一次针对C2=C3,一次针对C1=C2,因此您可以看到两者。这也解释了operator+=的行为。

如果您想避免以x为参考,请参阅格子呢的回答。

答案 2 :(得分:0)

请参阅Class& operator=(Class);Class operator+=(Class);他们将对象作为参数(而非参考)。因此,销毁那些临时对象会调用析构函数。

刚刚注意到上面有更多评论解释这个......:)