【问题标题】:Exception thrown in a Constructor构造函数中抛出的异常
【发布时间】:2019-10-03 13:32:42
【问题描述】:

我试图了解当构造函数抛出异常时会出现什么问题。

例如这段代码的一部分:

#include <iostream>

class X
{
public:
    X(int);
    ~X();
private:
    int* m;
};

X::X(int y)
{
    m = new int(y);
    throw std::exception();
}

X::~X()
{
    delete m;
    std::cout << "Destructor" << std::endl;
}

//---------------------------------------
int main()
{
    try
    {
        X a(4);
    }
    catch (const std::exception&)
    {
        std::cout << "ex" << std::endl;
    }
    system("pause");
    // output 
    /*  ex
        Press any key to continue . . .
    */
}

没有调用析构函数,所以这是内存泄漏!

1) 不使用任何智能指针是否可以解决这个问题?

2) 我的主要问题是当构造函数抛出异常时会出现什么问题(例如,当我们有一个层次结构的类,或者可能抛出异常的类成员时)?

【问题讨论】:

  • 这就是为什么我们有RAII。在您的情况下,如果 mstd::unique_ptr&lt;int&gt;,则不会有泄漏。
  • “是否可以在不使用任何智能指针的情况下解决这个问题?” - 奇怪的问题,因为这个问题是由于缺少使用智能指针引起的
  • 不使用智能指针?当然,您可能会捕获异常,删除m,然后像往常一样重新抛出。

标签: c++


【解决方案1】:

我的主要问题是构造函数抛出异常时会出现什么问题

就像一般的抛出一样,构造函数没有什么特别之处。

C++ 被设计为在构造函数中包含 throws。

你的例子:

m = new int(y);
throw std::exception();

哪里都不好。

用途:

auto m = std::make_unique<int>(y);
throw std::exception();

改为。

【讨论】:

  • 在任何地方都很糟糕 - 实际上,如果随后调用析构函数,则在成员函数中不是 OP 的情况。注意m是成员变量,不是自动变量。
  • @DanielLangr 谢谢,没听懂。
  • @FrançoisAndrieux 很好的函数 try-blocks 并不特定于构造函数,它们只是恰好是从成员初始化器中立即捕获异常的唯一方法。
猜你喜欢
  • 2011-11-04
  • 2019-03-11
  • 2014-11-03
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 2010-10-29
  • 2017-11-07
  • 2019-07-11
相关资源
最近更新 更多