如果构造函数抛出异常,如何删除对象?

嘉里

因此,我们有一个构造函数,可以根据传递给它的参数引发异常,但是如果发生这种情况,我们不知道如何删除该对象。代码的重要部分:

try
{
    GameBase *gameptr = GameBase::getGame(argc, argv);
    if (gameptr == 0)
    {
        std::cout << "Correct usage: " << argv[PROGRAM_NAME] << " " << "TicTacToe" << std::endl;
        return NO_GAME;
    }
    else
    {
        gameptr->play();
    }
    delete gameptr;
}
catch (error e)
{
    if (e == INVALID_DIMENSION)
    {
        std::cout << "Win condition is larger than the length of the board." << std::endl;
        return e;
    }
}
catch (...)
{
    std::cout << "An exception was caught (probably bad_alloc from new operator)" << std::endl;
    return GENERIC_ERROR;
}

在第三行中,GameBase::getGame()调用派生自其中一个游戏的构造函数,GameBase并返回指向该游戏的指针,并且这些构造函数可以引发异常。问题是,gameptr如果发生这种情况,我们如何删除指向的(部分?)对象如果引发异常,我们将退出的范围,gameptr因为我们离开了try块并且无法调用delete gameptr

尼尔

要评估异常安全性,您需要在中提供有关对象构造的更多详细信息GameBase::getGame

规则是,如果抛出构造函数,则不会创建对象,因此不会调用析构函数。关联的内存分配也被释放(即对象本身的内存)。

问题就变成了,如何开始分配内存?如果带有new GameBase(...),则无需取消分配或删除结果指针-运行时将释放内存。


为了清楚起见,已经构造的成员变量将如何处理;除了“父”对象外,它们都被破坏。考虑示例代码;

#include <iostream>
using namespace std;
struct M {
    M() { cout << "M ctor" << endl; }
    ~M() { cout << "M dtor" << endl; }
};
struct C {
    M m_;
    C() { cout << "C ctor" << endl; throw exception(); }
    ~C() { cout << "C dtor" << endl; }
};
auto main() -> int {
    try {
        C c;
    }
    catch (exception& e) {
        cout << e.what() << endl;
    }
}

输出是;

M ctor
C ctor
M dtor
std::exception

如果M m_要动态分配成员,则在裸指针上使用aunique_ptr或a shared_ptr,并允许智能指针为您管理对象;如下;

#include <iostream>
#include <memory>
using namespace std;
struct M {
    M() { cout << "M ctor" << endl; }
    ~M() { cout << "M dtor" << endl; }
};
struct C {
    unique_ptr<M> m_;
    C() : m_(new M()) { cout << "C ctor" << endl; throw exception(); }
    ~C() { cout << "C dtor" << endl; }
};

这里的输出反映了上面的输出。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如果构造函数抛出异常会怎样?

如何断言构造函数中抛出的异常?

构造函数抛出异常

从构造函数抛出异常?

如果文件在构造函数中不存在,则抛出异常,并在main()中创建对象时尝试/捕获它(如果好的话)-开始使用该对象

如何使用ByteBuddy代理处理构造函数抛出的异常?

如果其DataContext类构造函数抛出异常,则不显示窗口的最佳方法

抛出异常时保证复制省略和删除复制/移动构造函数

如何检测构造函数是否为带有抛出析构函数的异常

如果类的构造函数是内部的,如何创建对象

如果检测到构造不良的树,将抛出什么异常?

如何捕获构造函数异常?

如何编写异常的构造函数

如何构造具有删除的析构函数的动态对象?

如何使用基于 C# 中自定义异常构造的函数抛出自定义异常?

构造函数异常和隐式删除

std :: vector默认构造函数可以抛出异常吗

构造函数抛出异常后可以调用finalize吗?

当网络边缘的构造函数抛出异常时,避免使用SIGTRAP

参数化测试以检查构造函数是否抛出异常

构造函数可以抛出运行时异常吗?

Java在超级属性的子构造函数中抛出异常

如何在异步函数中抛出异常?

如何使Swift 2函数抛出异常

如何找出函数可能抛出的异常?

如果分母为 0,则抛出 ZeroCheck 异常对象

如果表达式为假,则抛出异常的标准函数?

尝试从列表视图中删除对象时抛出异常

如何我告诉Springdata存储库的删除方法如果一个实体不存在不抛出异常?