这编译,但我从未在任何其他代码中看到它。这样安全吗?
Testclass():sources(new int[32]){}
而不是:
Testclass(){
sources = new int[32];
}
答案 0 :(得分:10)
使用:
Testclass():sources(new int[32]){}
这是使用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]) {}
};
如果new Huge[10000]
抛出异常,分配给ints
的内存将泄漏!
在这种情况下,function-try-block可能很有用。见这些:
如果你想到这个异常安全问题,你很快就会意识到如果一个班级只管理一个资源,那么生活会更容易。如果一个类管理多个资源,那么您将无法确定哪个在构件初始化列表中引发了异常,因此,您将无法决定在哪个资源中取消分配function-try-block的catch
块。资源泄漏是注定的。
但是,如果一个类需要多个资源,那么首先将每个不同的类型资源封装在一个类中,并将这些资源管理类的对象声明为您的成员类。
答案 1 :(得分:0)
如果您使用奇怪的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...
}