-1

我有一个包含联合作为字段的类。联合是指向两个不同类的指针。作为第二个字段,我的类包含一个标志,通知当前存储的是哪种类型。

class Item {
    std::string *title;
    bool who_am_I;
    union { Submenu *smenu; Function *call; } content;
    public:
    bool am_I_a_submenu();
    bool am_I_a_function();
    Submenu *give_me_submenu();
    Function *give_me_function();
    /*(...)*/
};

现在,在每次使用我的“give_me”方法之前,我敦促用户通过访问标志的适当方法检查类型,即“am_I”方法。不过,如果用户碰巧忘记了它,我希望我的库抛出适当的异常。我可以在不检查“give_me”方法中的标志的情况下这样做吗?我问是因为这意味着在正常使用中该标志被不必要地检查了两次。

我想知道一旦出现类型冲突导致程序故障,c++ 是否会在构建异常中抛出一些异常以及何时会抛出一些异常。或者也许我应该以其他方式处理这种情况,最好还是不仔细检查标志。

4

3 回答 3

4

好的,首先......你为什么要关心标志是否被检查了两次?这真的是你的产品中一个严重的性能瓶颈,分析表明必须优化吗?我非常怀疑。

但即使是性能瓶颈,还有什么更重要的呢?在我看来,一个正常运行且不会崩溃的应用程序对于极少量的额外开销来说是一个可以接受的折衷方案。

但是您可能应该重新设计您的界面,以便用户始终知道他拥有什么并且不会犯这样的错误。

于 2013-01-23T23:41:56.443 回答
1

无法检查 union 中存储的内容。如果您使用联合,则由您来确保始终访问正确的元素。读错是未定义的行为,不会抛出异常。

我不知道你在做什么,但我建议你根本不要使用union。这是一种节省一些内存的老式方法,不值得它可能引入的错误。在您的情况下,它根本不节省内存(由于内存对齐,前面的布尔值占用的内存与指针一样多)。

于 2013-01-23T23:41:48.417 回答
0

通过使用联合,您告诉编译器这两种类型是兼容的。通常从两者转换会导致编译时问题,因为没有用户指定的转换,也没有默认转换,但是由于您将其定义为联合,因此对这两种类型都有默认转换。

我假设在这种情况下额外调用检查布尔值可能不会太贵。

于 2013-01-23T23:39:23.507 回答