jeudi 2 avril 2015

How to make sure your object is zero-initialized?

Initialization is a complex topic now since C++11 has changed meaning and syntax of various initialization constructs. I was unable to gather good enough info on it from other questions. But see, for example, Writing a Default Constructor Forces Zero-Initialization?.


The concrete problem I'm facing is: I want to make sure members of my classes are zeroed out both for (1) classes which declare a default c-tor, and for (2) those which don't.


For (2), initializing with {} does the job because it's the syntax for value-initialization, which translates to zero-initialization, or to aggregate initialization if your class is an aggregate - case in which members for which no initializer was provided (all!) are zero-initialized.


But for (1) I'm still not sure what would be the best approach. From all info I gather I learned that if you provide a default c-tor (e.g. for setting some of the members to some values), you must explicitly zero remaining members, otherwise the syntax MyClass c = MyClass(); or the C++11 MyClass c{}; will not do the job. In other words, value-initialization in this case means just calling your c-tor, and that's it (no zero-ing).


You run into the same situation if you declare a c-tor that takes values, and sets those values to a subset of the members, but you'd like other members to be zero-ed: there is no shorthand for doing it - I'm thinking about 3 options:



class MyClass
{
int a;
int b;
int c;

MyClass(int a)
{
this->a = a;
// now b and c have indeterminate values, what to do? (before setting 'a')


// option #1
*this = MyClass{}; // we lost the ability to do this since it requires default c-tor which is inhibited by declaring this c-tor; even if we declare one (private), it needs to explicitly zero members one-by-one

// option #2
std::memset(this, 0, sizeof(*this)); // ugly C call, only works for PODs (which require, among other things, a default c-tor defaulted on first declaration)

// option #3
// don't declare this c-tor, but instead use the "named constructor idiom"/factory below
}


static MyClass create(int a)
{
MyClass obj{}; // will zero-initialize since there are no c-tors
obj.a = a;
return obj;
}
};


Is my reasoning correct? Which of the 3 options would you choose?


Aucun commentaire:

Enregistrer un commentaire