2013-03-28 94 views
0

之前抛出异常防止构造C++通过构造函数体

我想一个类来throw其构造身体的大括号{利用自己的成员函数,以防止施工前的异常。我所定义的成员函数,它的目的仅仅是无条件throw异常,与任意选择的非void返回类型和一个伪数据成员,其类型返回类型相匹配,这样我可以通过构建与该数据成员触发throw在构造函数初始化器列表中调用所述成员函数。这是有效的,但并不优雅,因为在非玩具类中,虚拟变量不能用于其他目的,只能为成员函数运行提供借口,并且成员函数的非返回类型除了用于其他用途外,有一个借口可以通过相同类型的虚拟数据成员的构造函数来调用它。

这个玩具编译但不优雅:

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 

没有虚拟变量,是有办法的大括号之前抛出一个异常{的构造函数体?

+1

看到这个线程:http://stackoverflow.com/questions/2672398/throw-exception-from-constructor-initializer? – taocp 2013-03-28 02:23:30

+0

@Ken White,我不是特别想创建一个单例。一般来说,我只想知道如何在构造函数的正文之前防止构造。 – CodeBricks 2013-03-28 02:25:16

+0

明白了。 :-)我看到@SongWang发布并删除了我的评论的链接;一定发生了,就像你回答。 – 2013-03-28 02:26:30

回答

1

你能避免功能的假返回值是这样的:

bool called = (function(), true); 

逗号运营商在右侧的两个表达式计算表达式反过来,丢弃所有,但最后的结果。我想知道的是,为什么你坚持要在开启花括号之前这样做。你究竟想在这里达到什么目的,你不能在函数中调用函数作为体内的第一件事情?

需要注意的是,如果你想尽可能早地放弃,这样做,在一个单独的基类(您可以使用有私有继承)可能是最好的解决方案。这是唯一的解决方案,可以阻止您构建其他基地,而您的解决方案不会。

+0

要回答你的问题:我试图尽可能防止施工,而不是为了性能原因在ctor主体中。我想在某些运行时确定的用例中阻止构造。在这些情况下,我希望在昂贵的数据成员依次构建之前阻止构建。 – CodeBricks 2013-03-29 16:00:28

+0

在这种情况下,第一个基类的构造函数将是一个好地方。不过,我不相信你的方法是有限的。分配内存和处理异常是一项昂贵的操作,所以我宁愿避免这种情况。这是你的决定。祝你好运! – 2013-03-29 17:41:27

+0

我假设你的'bool called =(function(),true);'逗号运算符方法是类内定义数据成员初始值设定项的一部分。在ctor初始化器中有没有办法做到这一点? – CodeBricks 2013-03-29 18:45:36

2

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

需要注意的是GNU调试gdb的旧版本(几年前)未能就这种异常中断。

但是,工作与Visual C++ OK,我相信也与GNU工具链的现代版本。

+0

+1,很好的答案,谢谢。给了一个加票,但我必须选择一个答案来接受,并且接受的答案除了继承之外还提供了一个额外的解决方案。 – CodeBricks 2013-03-29 23:42:48