在构造函数的成员初始化器列表中使用new

joh*_*ers 7 c++

这编译,但我从来没有在任何其他代码中看到它.安全吗?

Testclass():sources(new int[32]){}
Run Code Online (Sandbox Code Playgroud)

代替:

Testclass(){
    sources = new int[32];
}
Run Code Online (Sandbox Code Playgroud)

Naw*_*waz 12

使用:

Testclass():sources(new int[32]){}
Run Code Online (Sandbox Code Playgroud)

这是使用member-initialization-list,这是初始化成员的首选方法.

通过"安全"或"好"你可能意味着,它是否是异常安全的?如果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]) {}
};
Run Code Online (Sandbox Code Playgroud)

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

在这种情况下,function-try-block可能很有用.看到这些:

如果你想到这个异常安全问题,你很快就会意识到,如果一个类只管理一个资源,那么生活会更容易.如果一个类管理多个资源,那么您将无法确定哪个在构件初始化列表中引发了异常,因此,您将无法决定在哪个资源中取消分配该catch块功能试块.资源泄漏是注定的.

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

  • 啊,功能尝试块.我从来没有使用过一个,但是我可以想象那些没有在"隐藏的C++特性"问题上发现它们的人们产生的混乱SO :) (2认同)