Sign in to follow this  
GiantPaul

C++ class initializing variables to 0

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this