8

这可以编译,但我从未在任何其他代码中看到它。安全吗?

Testclass():sources(new int[32]){}

代替:

Testclass(){
    sources = new int[32];
}
4

2 回答 2

14

采用:

Testclass():sources(new int[32]){}

这是使用成员初始化列表,这是初始化成员的首选方式。

您可能指的是“安全”或“好的”,它是否是异常安全的?如果new抛出 bad_alloc 异常怎么办?

好吧,在这种情况下,不会调用析构函数,因为对象不是完全构造的,因为没有执行构造函数体。如果您在初始化列表中获取了任何资源,则可能存在资源泄漏。

考虑到这一点,

class X
{
    int  *ints;  // Order of declaration matters!
    Huge *huges; // It ensures that huges will be initialized after ints

    X() : ints(new int[32]), huges(new Huge[10000]) {}
};

如果new Huge[10000]抛出异常,分配的内存ints会泄漏!

在这种情况下,function-try-block会很有用。见这些:

如果您考虑这个异常安全问题,您很快就会意识到,如果一个类只管理一个资源,那么生活会更轻松。如果一个类管理多个资源,那么您将无法确定哪个类在成员初始化列表中引发了异常,因此,您将无法确定要释放哪个类catch功能尝试块的块。资源泄漏是注定的。

但是,如果一个类需要多个资源,那么首先将每种不同类型的资源封装在一个类中,并将这些资源管理类的对象声明为类的成员。

于 2013-02-04T06:55:44.283 回答
1

如果您使用奇怪的 C++ 语法在构造函数的初始值设定项列表中使用 try/catch 块,那也没关系:

class C {
    int *n;
public:
    C();
};

C::C()
try : n(new int[100])
{
  // do stuff here
}
catch(...)
{
  // handle exceptions
}

int main()
{
    C c; // Should be safe...
}
于 2013-02-04T08:25:13.557 回答