0

Is there a way to initialize all the data members of a class that has a user defined constructor?

class CTest
{
private: 
    int a = 0;
    BYTE b; CHAR* c; int d; int e; int f; int g;
public:
    CTest() b:(0)
    {
        c = 0;
    }
};

Imagine my class has 100 data members, and I want to initialize them all to zero.

Doing it 1 by 1 is not optimal. The workaround I'm using right now is: I put all those 100 data members in a structure which is the base for my class

like

class : public base_with_all_members

and when I want to reset all the members I just do the following in the constructor or in a initialize() function for example.

*dynamic_cast<base_with_all_members*>(this) = {};

Which does properly clears all members.

Jts
  • 3,447
  • 1
  • 11
  • 14
  • I meant: *dynamic_cast(this) = {}; – Jts Feb 01 '16 at 05:27
  • 15
    Why does your class have that many members in the first place? Sounds like a bad idea. – Baum mit Augen Feb 01 '16 at 05:29
  • 2
    I second @BaummitAugen 's comment. A class with that many members is an unmaintainable design. You've just run into the first aspect of that. Instead of finding a technical solution, consider an alternative design. – Ami Tavory Feb 01 '16 at 05:36
  • Will in-class brace-or-equal initializer meet your need? If you just want to initializer all members to zero, you may consider making an aggregate and performing zero initialization with `{}`. – Lingxi Feb 01 '16 at 05:43
  • Take a look [here](http://stackoverflow.com/a/6891731/5756174). – jblixr Feb 01 '16 at 05:43
  • Okay, maybe I made a mistake by over exaggerating. It does not have 230 data members, it has probably around 100. And the reason why it has that many is because it's a huge project, and it's the main class in the project, so every other class relies on it. The design could have been better, but it's not because I started it when I was new at C++. – Jts Feb 01 '16 at 05:43
  • @Lingxi I think you have not fully read my question since that's what I'm currently doing. I was wondering if there's a better way. – Jts Feb 01 '16 at 05:58
  • @jblixr I have unique_ptr and a mutex in my class, and they cannot be copied so your solution doesn't work... – Jts Feb 01 '16 at 05:58
  • 3
    @Jose If so then you should have mentioned all these requirements in your question. – jblixr Feb 01 '16 at 06:49
  • 4
    I second what the people before me said. The fact that you didn't know C++ very well *back then* is no reason not to refactor *now*. – StoryTeller - Unslander Monica Feb 01 '16 at 07:12
  • Instead of 100 named members use an **array**. E.g. `std::array` or `std::vector`. – Cheers and hth. - Alf Feb 01 '16 at 07:25
  • Also covered [here](http://stackoverflow.com/questions/22975262/constructor-to-specify-zero-initialization-of-all-builtin-members) (probably a duplicate actually) – M.M Feb 14 '16 at 20:55

2 Answers2

4

The easiest will probably be to use the newer syntax for default value initialisation in this case. Sure it may be "not-optimal" in terms of typing time, but the generated code should be comparable.

class CTest
{
private: 
    int a = 0;
    BYTE b = 0;
    CHAR* c = nullptr;
    int d = 0;
    int e = 0;
    int f = 0;
    int g = 0;
public:
    CTest(): d(42)
    // initialiser list only needed is this particular
    // constructor doesn't initialise the value to 0
    {
    }
};

Another alternative is to farm off the data members to a POD style "data structure" and then initialise that in the class's constructor;

struct POD {
  int a;
  int b;
  std::unique_ptr<int> c;
  // etc.
};

class CTest {
  POD data_ = { };
};

Further alternatives could include using a static of the above POD data structure to initialise the member POD.


You have mentioned in the comments that you have some data members that cannot be copied (but presumably can be moved), and that you are looking for some form of a "reset" function as well. The POD sample can be modified to;

class CTest {
  POD data_ = { };
public:
  void reset()
  {
    data_ = POD{}; // caters for moveable and copiable types
  }
};

Sample here.


On a side note; this is a large number of data members. Maybe some further data division would be a good idea as well. Sure, I accept that this may be a really peculiar situation, but it may be worthwhile to consider some re-factoring anyway.

Community
  • 1
  • 1
Niall
  • 30,036
  • 10
  • 99
  • 142
  • Hope the edit is OK, if not you may rollback. – legends2k Feb 01 '16 at 07:24
  • I'm already using the second approach "farm off" the data members from a POD data structure, and the reason is because I can reset it anytime I want. I also mentioned your first approach on my question (u can see i did set a, b, c in different ways). The problem is that with such approach, I can't reset the class, I'd have to delete it and create a new one (because it has mutex, and uniqueptrs which cannot be copied) therefore I can't just do *myclassptr = {} . – Jts Feb 01 '16 at 07:25
  • @Jose, could you make use of `std::move`? You could then "move" and "empty or reset" object into the data member. – Niall Feb 01 '16 at 07:28
3

Why not this? Then it would be in just one location for all of your constructors.

class Foo {
    public:
        Foo(): b(3) {}

    private:
        int a = 0;
        int b = 0;
        int c = 0;
        int d = 0;
        int e = 0;
};
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173