Sign in to follow this  
Tachikoma

C++ Constructors and Initializing Member Data

Recommended Posts

Tachikoma    575
Say I have a large class, containing dozens of individual member data which needs to be reset to 0 as soon as the class is constructed. Obviously, one could reset each individual member data to 0 via the constructor...
class MyClass
   {
   public:
   MyClass(void);
   ~MyClass(void) {};
   
   int Data1, Data2, Data3; /* ...and so on... */
   };

MyClass::MyClass(void) 
   {Data1 = Data2 = Data3 = 0; /* ...and so on... */ }
However, if I were to edit the class and add or remove member data, I would have to sync the changes in the constructor where the individual member data is initialized. The method can be *very* tedious if I need to manage lots of things in the class. So I was in the habit of using memset() in the constructor to nuke everything to 0 automatically:
MyClass::MyClass(void) 
   {memset(this, 0, sizeof(class MyClass)); }
It's a bad habit. Yes I know. (Some Cpp purists would probably crucify me for doing it.) It's been said there is no quarantee the "this" pointer is defined while the constructor is being called, plus memset() will obliterate "hidden" pointer tables if you declare virtual member functions. Another method is to placing memset() inside a speparate member function, say...
MyClass::Reset(void) 
   {memset(this, 0, sizeof(class MyClass)); /* ok to use if no vitual functions are declared */ }
...then call it externally after the MyClass::MyClass() constuctor is finished. The only drawback is that it removes the benefit of "automated" initialization like you see with constructors. Is there a funky way of automatically (and safely) clearing a *large* class without resorting to tedious constructor maintenance or memset() hacks? Suggestions appreciated!

Share this post


Link to post
Share on other sites
Washu    7829
Quote:
Original post by Tachikoma
Say I have a large class, containing dozens of individual member data which needs to be reset to 0 as soon as the class is constructed. Obviously, one could reset each individual member data to 0 via the constructor...

Ok...sounds like the class has too many responsibilities, but I've seen other cases where this was probable
Quote:

However, if I were to edit the class and add or remove member data, I would have to sync the changes in the constructor where the individual member data is initialized. The method can be *very* tedious if I need to manage lots of things in the class. So I was in the habit of using memset() in the constructor to nuke everything to 0 automatically:

It's a bad habit. Yes I know. (Some Cpp purists would probably crucify me for doing it.) It's been said there is no quarantee the "this" pointer is defined while the constructor is being called, plus memset() will obliterate "hidden" pointer tables if you declare virtual member functions.

Memsetting any non-pody type class to 0 will have undefined behavior, which can include destroying implementation specific information, such destroying the pointer to the v-table. The this pointer IS well defined during construction (even in the initializer list) and destruction. It is guaranteed to be by the standard. I don't know who told you otherwise but you should go find them and lord your newly aquired knowledge over them.
Quote:

Another method is to placing memset() inside a speparate member function, say...
...then call it externally after the MyClass::MyClass() constuctor is finished. The only drawback is that it removes the benefit of "automated" initialization like you see with constructors.

Again, that has undefined behavior for non-pod types.

Quote:

Is there a funky way of automatically (and safely) clearing a *large* class without resorting to tedious constructor maintenance or memset() hacks? Suggestions appreciated!

Don't make large classes? You will find that large classes tend to be extremely hard to maintain in the long run, although in some cases not easily "avoidable".

Share this post


Link to post
Share on other sites
Tachikoma    575
Thanks for the info.

I managed to find a work-around. Not the most elegant solution, but it seems to work ok for now, cosidering how lazy i am.

class MyClass
{
public:
MyClass(void);
~MyClass(void) {};

struct datagroup1
{
int Data1, Data2, Data3; /* ...and so on... */
} Group1;

MyClass::MyClass(void)
{Group1 = datagroup1();}


Apparently struct declarations are treated as POD, and Cpp will zero them out by default if I do this in the constructor:
Group1 = datagroup1();





I have another unrelated questions: Is template specialization for a group of types possible? Say for example I use the template shown below, and I want to specialize the "DoStuff" member function for both float and double types. Is there a way to group both specializations into a single implementation, instead of replicating code? If not, can I conditionally include (or exclude) parts of the template code, depending on the type?

template <typename T> class A
{
public:
A() {}
~A() {}

<T> DoStuff(<T> NewData)
{return /* Do stuff with NewData */;}

<float> DoStuff(<float> NewData)
{return /* Do stuff with NewData */;}

<double> DoStuff(<double> NewData)
{return /* Do stuff with NewData */;}
};


Share this post


Link to post
Share on other sites
TheTroll    883
just an idea for you.

#define MAX_DATA 30

class MyClass
{
public:
MyClass(void);
~MyClass(void) {};

int Data[MAX_DATA]
};

MyClass::MyClass(void)
{
for (int x = 0; x < MAX_DATA ; x++)
Data[x] = 0;
}


anytime you need to add more data you just increae the value of MAX_DATA

theTroll

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