C++ class initializing variables to 0

Started by
6 comments, last by Antheus 14 years, 7 months ago
If I make a C++ class with a few pages of variables: char, int .... Then is there a one line command to initialize all variables to 0? Right now I do it in the constructor by taking every single variable one at a time and doing the "= 0". The reason I ask is because if I add a new variable and forget to set it to 0 then it creates problems.
Advertisement
You could do
memset(this,0,sizeof(MyClass));
in the constructor.

EDIT: The answers below suggest this isn't a sane idea. I've been using C too much at work.

It's probably better practice to try to initialise all values to useful data when the class is instantiated, by passing in a struct or somesuch.

EDIT: Ah, see Antheus' answer below.
Quote:Original post by GiantPaul
If I make a C++ class with a few pages of variables: char, int ....

That is a problem in itself.


Quote:Then is there a one line command to initialize all variables to 0?

No.

If your class is POD (basically a C struct, which is different from C++ struct), then you can zero the memory via memset or ZeroMemory, but that doesn't work for non-POD classes.

Quote:Right now I do it in the constructor by taking every single variable one at a time and doing the "= 0".


Initializer lists:
class Foo {  int x;  char c;  float f;  Foo()     : x(0)    , c(' ')    , f(0.0)  {  }};


Quote:The reason I ask is because if I add a new variable and forget to set it to 0 then it creates problems.

The reason C++ is still used is for this very reason. It leaves the choice of whether a variable should be initialized at the hands of the user. Sometimes, leaving variables deliberately uninitialized can be used for performance reasons.

But, "several pages of variables" is a problem in itself. It usually implies there is way too much functionality crammed into single class.

Quote:memset(this,0,sizeof(MyClass));

in the constructor. I'm not a C++ guru so someone else might come up with some arcane reason why that's a bad idea, but it should clear all values in the class to zero.


Unless the class is polymorphic, in which case this will almost certainly overwrite the vtable. Or if the class contains non-POD types (std::string, std::vector), in which case it will destroy their internal state and cause undefined behavior.
A few pages sounds awfully much for a single class :) but I guess you could do it like this for example (only if all data in the class are supposed to be zeroed)

MyClass::MyClass(){   std::memset(this, 0, sizeof(MyClass));}


If the class has any virtual functions this might not work.

This is the safer approach
MyClass::MyClass() : var1(0), var2(0){}



Instead of having a class full of (I guess int, floats etc.. base types), divide it into smaller classes and let each class take care of the zeroing of its memory.
Blekinge Institute of Technology
Twitter [twitter]devmoon[/twitter]
Homepage http://devmoon.se
Stream http://twitch.tv/devmoon
You have to initialize each individually, there's no way around it.

Well I guess you could use memset to clear out a group of variables that are declared consecutivly, but I don't think anyone in their right mind would do something like that.
--------------------------------------Not All Martyrs See Divinity, But At Least You Tried
If you are using/are allowed to use/are willing to use managed C++ with .Net, then you can make use of reflection to get all the properties and set them to 0.

As already said, though, most problably you should think twice on your design, if you have all those members. Perhaps some of them migh be replaced by arrays?
Put the variables in a struct. Instanciate the struct in the class.
Zeromem the instance of the struct wherever you need.
Profit.
P.S.
Oh, and as others above pointed, there is something horribly wrong in a class with "pages" of variables.
Rusenec
There is way too much technical discussion, for what is really a design problem. Obviously it's possible to find a way to save typing, but it's possible to change the design for more benefit.

class Foo {public:  int posx;  int posy;  int posz;  };
Clearly, this stores the location. But it's better done like this:
class Position3D {public:  Position3D(int x = 0, int y = 0, int z = 0) : posx(x), posy(y), posz(z) {}  int posx;  int posy;  int posz;};
And now, using this in Foo:
class Foo {public:  Position3D pos;};
No initialization necessary. Not for Position3D, not for Foo, since compiler knows how to auto initialize the members. If another position were needed, just adding it as member is enough.

For this reason, it makes sense to encapsulate variables and provide default constructors, especially if default values will commonly be used.

This is also the reasoning behind standard library:
class Foo {public:  Position3D pos; // default 0,0,0  std::string s;  // empty string ""  std::vector<int> ints; // no elements, reserves some space (maybe 10 elements)};


So instead of trying to hammer a round peg into square hole, review the design. Why so many variables, which belong together, which could be grouped into same type, then extract them into classes with default constructor.

This topic is closed to new replies.

Advertisement