This compiles, but I've never seen it in any other code. Is it safe?
Testclass():sources(new int[32]){}
Instead of:
Testclass(){
sources = new int[32];
}
This compiles, but I've never seen it in any other code. Is it safe?
Testclass():sources(new int[32]){}
Instead of:
Testclass(){
sources = new int[32];
}
Use:
Testclass():sources(new int[32]){}
This is using member-initialization-list which is the preferred way to initialize members.
By "safe" or "okay" you probably meant, whether it is exception-safe? What if new
throws the bad_alloc exception?
Well, in that case, the destructor will not be called, because the object is not fully-constructed, as constructor-body is not executed. There may be a resource leak if you've acquired any resource in the initialization list.
Consider this,
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]) {}
};
If new Huge[10000]
throws an exception, the memory allocated toints
will leak!
In such cases, function-try-block can be useful. See these:
If you think about this problem of exception-safety, you will soon realize that if a class manages just one resource, then the life will be easier. If a single class manages more than one resource, then you wouldn't be able to decide which one threw an exception in the member-initialization-list, and consequently, you wouldn't be able to decide which one is to be deallocated in the catch
block of function-try-block. A resource leak is destined.
However, if a class needs more than one resource, then first you encapsulate each of the different type of resource in a class, and declare objects of these resource-managing class as a member of your class.
It's okay if you use the weird C++ syntax for using a try/catch block in a constructor's initializer list:
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...
}