1

考虑以下情况:

struct X { ... };

struct Y
{
     Y(...);

     ...

     X x;

     ...
}

X f()
{
    ...

    if (...)
        throw E;

    ...
}

Y::Y(...) :
    ... ,
    x(f()) ,
    ...
{
    ...
}

这里有任何未定义的行为吗?抛出 E 时,这样的设计是否存在任何陷阱或潜在问题?

更新:

Y::x可能不是 的唯一成员变量,可能不是类中的第一个成员变量,并且可能在init 列表Y的中途被初始化。Y::Y

4

2 回答 2

5

这里有任何未定义的行为吗?

否。 的构造Y已中止。

抛出 E 时,这样的设计是否存在任何陷阱或潜在问题?

没有Y被创建,所以没有析构函数可以调用。完全构造的元素的析构函数,那些之前x在类主体中声明的元素,将被自动调用(否则你怎么知道你抛出的初始化列表有多远)。如果你需要销毁任何东西,那么你必须捕获异常并自己销毁它。你不能吸收异常,你可以重新抛出它,抛出一个新的异常,或者什么都不做,无论如何都会导致异常被重新抛出。对于您的特定用例,不应该有任何东西可以破坏,因为构造函数主体根本不会被调用。

于 2013-01-06T22:03:05.873 回答
2

When an exception is throwing during the construction of an object, the destructors of all fully constructed subobjects are called. That is, assuming your type X throwing an exception correctly cleans up any resources it may have allocated before the exception was thrown, there is no issue.

于 2013-01-06T22:16:04.127 回答