Instead of having to remember to initialize a simple 'C' structure, I might derive from it and zero it in the constructor like this:
struct MY_STRUCT { int n1; int n2; }; class CMyStruct : public MY_STRUCT { public: CMyStruct() { memset(this, 0, sizeof(MY_STRUCT)); } };
This trick is often used to initialize Win32 structures and can sometimes set the ubiquitous cbSize member.
Now, as long as there isn't a virtual function table for the memset call to destroy, is this a safe practice?
Problem of initialization in C++ Therefore, when objects are created, the members of the object cannot be initialized directly and this problem of not being able to initialize data members is known as the problem of initialization.
An initializer for a structure is a brace-enclosed comma-separated list of values, and for a union, a brace-enclosed single value. The initializer is preceded by an equal sign ( = ).
Structure members cannot be initialized with declaration.
Que: Can we initialize structure members within structure definition? No! We cannot initialize a structure members with its declaration, consider the given code (that is incorrect and compiler generates error).
You can simply value-initialize the base, and all its members will be zero'ed out. This is guaranteed
struct MY_STRUCT { int n1; int n2; }; class CMyStruct : public MY_STRUCT { public: CMyStruct():MY_STRUCT() { } };
For this to work, there should be no user declared constructor in the base class, like in your example.
No nasty memset
for that. It's not guaranteed that memset
works in your code, even though it should work in practice.
While my answer is still Ok, I find litb's answer quite superior to mine because:
So please, consider litb's answer before mine. In fact, I suggest the question's author to consider litb's answer as the right one.
Putting a true object (i.e. std::string) etc. inside will break, because the true object will be initialized before the memset, and then, overwritten by zeroes.
Using the initialization list doesn't work for g++ (I'm surprised...). Initialize it instead in the CMyStruct constructor body. It will be C++ friendly:
class CMyStruct : public MY_STRUCT { public: CMyStruct() { n1 = 0 ; n2 = 0 ; } };
P.S.: I assumed you did have no control over MY_STRUCT, of course. With control, you would have added the constructor directly inside MY_STRUCT and forgotten about inheritance. Note that you can add non-virtual methods to a C-like struct, and still have it behave as a struct.
EDIT: Added missing parenthesis, after Lou Franco's comment. Thanks!
EDIT 2 : I tried the code on g++, and for some reason, using the initialization list does not work. I corrected the code using the body constructor. The solution is still valid, though.
Please reevaluate my post, as the original code was changed (see changelog for more info).
EDIT 3 : After reading Rob's comment, I guess he has a point worthy of discussion: "Agreed, but this could be an enormous Win32 structure which may change with a new SDK, so a memset is future proof."
I disagree: Knowing Microsoft, it won't change because of their need for perfect backward compatibility. They will create instead an extended MY_STRUCTEx struct with the same initial layout as MY_STRUCT, with additionnal members at the end, and recognizable through a "size" member variable like the struct used for a RegisterWindow, IIRC.
So the only valid point remaining from Rob's comment is the "enormous" struct. In this case, perhaps a memset is more convenient, but you will have to make MY_STRUCT a variable member of CMyStruct instead of inheriting from it.
I see another hack, but I guess this would break because of possible struct alignment problem.
EDIT 4: Please take a look at Frank Krueger's solution. I can't promise it's portable (I guess it is), but it is still interesting from a technical viewpoint because it shows one case where, in C++, the "this" pointer "address" moves from its base class to its inherited class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With