通过在构造函数体之前抛出异常来防止构造

时间:2013-03-28 02:20:04

标签: c++ exception constructor throw ctor-initializer

C ++

我想要一个类throw在它的构造函数的主体打开大括号{之前的异常,通过使用它自己的成员函数来阻止构造。我定义了一个成员函数,其目的只是无条件地throw异常,具有任意选择的非void返回类型和类型与返回类型匹配的虚拟数据成员,因此我可以触发throw通过在构造函数初始化列表中调用所述成员函数来构造此数据成员。这有效但不优雅,因为在非玩具类中,虚拟变量不会用于其他目的,而是有成员函数运行的借口,而成员函数的非void返回类型不起作用其他目的,但有一个借口可以由相同类型的虚拟数据成员的构造函数调用。

这个玩具编译但不优雅:

class Toy
{
public:
    Toy() : dummy(preventer()) {}
private:
    int dummy;
    int preventer() {throw -1; return 0;}
};

#include <iostream>

int main()
{
    try
    {
        Toy t;
    }
    catch (const int& e)
    {
        std::cout << "caught the exception\n";
    }
    return 0;
}

控制台输出:

caught the exception

如果没有虚拟变量,有没有办法在构造函数体的开始大括号{之前抛出异常?

2 个答案:

答案 0 :(得分:2)

是的,您可以使用基类而不是数据成员,然后调用基类的构造函数。

请注意,旧版本的GNU调试器gdb(几年前)无法在此类异常中断。

但是,使用Visual C ++可以正常工作,我也相信现代版本的GNU工具链。

答案 1 :(得分:1)

您可以像这样避免函数的伪返回值:

bool called = (function(), true);

右边两个表达式之间的逗号运算符依次评估表达式,丢弃除最后一个结果之外的所有表达式。我想知道的是,为什么你坚持在开口花括号之前做到这一点。你究竟想在这里实现什么,你不能通过调用函数作为身体的第一件事来实现?

请注意,如果您想尽早中止,那么在单独的基类中执行此操作(您可以在那里使用私有继承)可能是最佳解决方案。它是唯一可以阻止构建其他碱基的解决方案,而解决方案却没有。