如果派生类析构函数抛出异常,基类析构函数会发生什么

Joh*_*itb 23 c++ destructor memory-leaks exception

它刚好发生在我身上,我想知道在下列情况下如何释放资源.

class Base {
  Resource *r;

public:
  Base() { /* ... */ }
  ~Base() {
    delete r; 
  }
};

class Derived : public Base {
public:
  Derived() { /* ... */ }
  ~Derived() {
    /* Suddenly something here throws! */
  }
};

int main() {
  try {
    Derived d;
  } catch(...) {
    /* what happened with Base::r !? */
  }
}
Run Code Online (Sandbox Code Playgroud)

如果派生类析构函数抛出,是否会调用基类析构函数?或者会有泄漏吗?

GMa*_*ckG 20

根据§15.2/ 2:

部分构造或部分销毁的对象将为其所有完全构造的子对象执行析构函数,即对于构造函数已完成执行且析构函数尚未开始执行的子对象.

所以应该调用基类析构函数.也就是说,就像我们知道这将清理基类:

#include <iostream>

struct foo
{
    ~foo()
    {
        std::cout << "clean" << std::endl;
    }
};

struct bar : foo
{
    bar()
    { // foo is initialized...
        throw 0; // ...so its destructor is run
    }
};

int main()
{
    try
    {
        bar b;
    }
    catch (...)
    {
        std::cerr << "caught" << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

这将清理成员:

#include <iostream>

struct foo
{
    ~foo()
    {
        std::cout << "clean" << std::endl;
    }
};

struct bar
{
    ~bar()
    { // f has been initialized...
        throw 0; // ...so its destructor will run
    }

    foo f;
};

int main()
{
    try
    {
        bar b;
    }
    catch (...)
    {
        std::cerr << "caught" << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

这也将清理基类:

#include <iostream>

struct foo
{
    ~foo()
    {
        std::cout << "clean" << std::endl;
    }
};

struct bar : foo
{
    ~bar()
    { // foo has been initialized...
        throw 0; // ...so its destructor will run
    }
};

int main()
{
    try
    {
        bar b;
    }
    catch (...)
    {
        std::cerr << "caught" << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我对报价的理解.