C ++函数调用,为什么使用析构函数?

时间:2019-01-20 11:42:59

标签: c++ function destructor

我试图理解C ++中更好的函数调用。我有以下代码:

class A{ 
  public:
    A() { cout << "hello\n"; }
    A(const A& obj) { cout << "world\n"; }
    ~A() { cout << "bye\n"; }

  virtual void print() { cout << "a\n"; }
};

A foo(A aobj)
{
    aobj.print();
    return aobj;
}

int main(){
  A a,b,c;
  foo(a);
  system("pause");
  return 0;
}

输出为:

hello //from calling A's default constructor

hello

hello

world //because we pass 'a' by value in funtion foo so the copy constructor is used


a

world //because foo returns by value so the copy constructor is used again

bye //?

bye //?

有人可以解释一下为什么析构函数最后被调用两次吗?是因为两个拷贝构造函数调用了吗?

谢谢您的时间!

3 个答案:

答案 0 :(得分:2)

“再见”被打印5次,因为~A()也被称为5次。对于对象abc,析构函数称为对象。然后,当您按值传递a时,会在foo中创建一个副本,然后将其销毁。最后,foo的返回类型是A的实例,当执行移至下一行时,该实例将被销毁。因此,~A()总共将被调用5次。

在对象生存期结束时调用析构函数以释放该对象使用的内存。

答案 1 :(得分:1)

创建了5个对象,因此将输出5个“ bye”。

但是,只有2个对象超出范围,并且在调用system("pause")之前(foo()的调用后 被破坏。因此,如果在应用程序退出时控制台窗口关闭,您可能没有机会看到这3个“再见”。

您可以通过引入另一个生存期较短的范围来强制这3个对象更快地超出范围,如下所示:

system("pause")

或者这样:

int main(){
    {
    A a,b,c;
    foo(a);
    }
    system("pause");
    return 0;
}

现在,所有5个对象都将超出范围并在对void doIt(){ A a,b,c; foo(a); } int main(){ doIt(); system("pause"); return 0; } 的调用之前被破坏。

答案 2 :(得分:-2)

尝试一下:

class A {
       public:
    A() { cout << "Default ctor → A::A()\n"; }
    ~A() { cout << "Default dtor → A::~A()\n"; }

    A(const A&) {
        cout << "Copy ctor → A::A(const A& rhs)\n";
    }
    A& operator=(const A& rhs) {
        cout << "Copy operator= → A& A::operator=(const A& rhs)\n";
        return *this;
    }

    A(const A&&) {
        cout << "Move ctor → A::A(const A&& rhs)\n";
    }
    A& operator=(const A&& rhs) {
        cout << "Move operator= → A& A::operator=(const A&& rhs)\n";
        return *this;
    }
};

还要获取 Effective Modern C ++ 的副本,并阅读第17项:了解特殊成员函数的生成。