how to properly initialize a class containing many data members? - c++

Suppose a class contains around 10 data members then what would be the proper way to initialize an object of that particular class? Create a constructor with 10 parameters or just provide a default constructor then use setter member functions or something else?
Basically I want to know how it is done in actual real life code?
thanks.

In actual real life code, I would be very reticent to have a class with 10 parameters that need to be set.
But also in real life, I know that this happens much more often than I would like. So here is what I would do:
First, evaluate your design. Do you really need all that stuff?
Second, if you really do need all that stuff, or if there's no way out due to a legacy design, then I would require every parameter in the constructor, and make the default constructor private. Everything should be initialized in an initialization list.
Sometimes when the data members and the class methods are sufficiently decoupled I would prefer to move all the data members to their own struct, and then have a member of that struct in the class. Take that struct by const reference and assign it in the init list. Make the struct member const.

Another [design] problem is that if you use class with that many arguments as a base class and then add more arguments (due to a requirement, for example), you may well forget to initialize them. So, yeah, refactor.

Isn't this really an OOP and design question?
What is the object here? Are all 10 fields attributes of that object? Can some be further grouped under another class?
Do you always have all 10 pieces of data when you need to instantiate the class? You can make constructors for the pieces you have and/or do setters/getters.

Related

In C++ whats the difference between setters and getters and constructors?

If we use constructors do we need to use setters and getters. I am totally confused between these terms could someone please elaborate.
If we use constructors do we need to use setters and getters
First of all you cannot have a class without a constructor, when you do not provide any compiler will generate them for you. You should not use setters and getters unrelated if you define your own constructor or not. When you design a class you design it's interface and then add member variables to implement that behavior and those members are internal representation of the class and outside world should not be aware of them - that is what data encapsulation is for and that's why we make them private or protected. When you add members first and then blindly provide getters and/or setters - that is a wrong approach to OOD.
Use constructors to create objects. Use getters to get information from an already existing object. Use setters to change an already existing object.
Any particular class may will need one or more of these things but not every class will need all of them. In particular immutable classes can't be modifed after they've been created so don't need setters.
The two things are very different.
A constructor is a function that is called by the system whenever an object is created. If you don't define one yourself, the compiler will provide a default one. Whatever happens, a constructor will be called exactly once for each object you create. Its purpose is usually to set up valid values for all members of the class.
By contrast, getters and setters are just regular functions — methods whose purpose is to provide access to individual members of a class (read and write acces, respectively). There is no requirement to provide one, and they are not automatically generated; conversely, if one is provided, it may be called as often as you like.
Hopefully it's clear how a constructor differs from set/getters.

Change number of members depending on constructor called

I need a template class, which has different members, depending on which ctor is called.
I managed to get a class, which has different members using sfinae with a base class (I did it almost like this SFINAE on member variable).
Now my question is, can I achieve a single template class, which has different members, depending on which ctor of the class is called?
Maybe someone can has an idea how to achieve this.
EDIT: I currently use boost::variant, but the problem is, that the largest object in the variant is huge, and the the smallest is ust a pointer. this is a real performance problem, because most of the time the pointer will be in the variant.
EDIT II: If this would work with a ctor it would be awesome, but if not, a factory-fuction would work as well.
EDIT III (or what I am trying to achieve):
I am currently making a DSL, which translates to C++.
Since I am trying to make polymorphism possible, I am only passing pointers to functions. Beacause some pointers are reference counted and some pointers are raw, depending on what the user wants, there can be shared_pointers and raw pointers of the same class. Thats why I can't make two different classes, because if a function is called on a pointer, it should be the same function, otherwise I have to overload all the fnctions, which would give me
2**n functions when the function has n arguments.
Thats why I am trying to create a class, which could eigther represents a raw pointer or a shared_ptr, based on what is passed to the ctor.
You should simply continue using variant<> but instead of storing your huge class as an object, store it as a pointer as well:
boost::variant<common_case*, huge_class*>
Since you say you usually store a pointer anyway, this doesn't cost you anything, and reclaims 100% of the wasted memory because all object pointers are the same size.

abstract classes and constructor in C++

I read this question "C++ Abstract Class: constructor yes or no?" and the answers belonging to it.
But according to answers, I understand that we need the constructor to initialize it data members, however I can use its member functions like setter functions in my derived class to initialize the data members, so Why is it important to define a constructor?
The default constructor definition and the member initializations make the class self contained regarding proper setup conditions (valid state).
Usage of setter methods to manipulate the class instance is optional for class clients (including inheriting classes).
You may consider adding more constructor signatures, that the clients can use to inititialze the class members with a single call, and don't require these applying additional setter calls.
It depends on the particular use case, what's more convenient and semantically correct in the end.
Two reasons:
To ensure the objects are always within a valid state.
You need a copy constructor to ensure that data gets copied correctly (e.g., no blind copies of dynamically allocated resources).
Probably more.

Should I create multiple classes?

This applies to several cases in my application:
I have 3 or 4 functions that belong together, one is a starting function that creates and frees the required memory structures and calls the other functions as appropriate. The other functions also call themselves repeatedly. Only the starting functions is called from outside, and only once or not at all per application-run.
Currently, I pass pointers to the memory structures from the starting function as function arguments, but the argument list is getting quite long in some cases.
Is there any argument against creating classes for all these cases and making the pointers to the memory structures members?
Definitely go for a class here. That's what objects and classes are designed for.
It seems to be a quite typical use case for classes: Just add the "memory structure" as protected member of the class and initiliaze it in the constructor.
The member functions (aka "method") than can work on the data.
If you have different, but similiar use cases, you may also make use of subclassing, so you create a base class with default implementation and create some derived class that overwrites some of the methods with an own implementation.
But note, that you could also use other members varibales to set the behaviour at runtime (e.g. a bool that is used to toggle on or off a specific behaviour).
Your question is too abstract to see what is the best solution for your case. Remember, often there are a lot of solutions - and so there is more than one good solution.
It sounds to me like these functions belong in a class - with the internal functions private or protected - likewise with the members.
Yes, relate them all within a class.
This will also give you a cleaner code which might help you minimize the functions' arguments lists.
In simple words an object can be anything you decide. Say a person. This is an object which I'll decide to define as a class if I'll write a program that needs to keep information regarding people.
There are much better explanations than this, just google/wikipedia it.

If the only thing that changes is the constructor should I still derive?

I have a class that has everything already implemented but its initialization process is different for every child class.
Is there a better idiom to replace the ctor? Is there something more generic/dynamic that I should use?
Or use static factory methods. This allows you to have different names for the "constructor" that shows the intent.
Does each subclass really represent a different concept than the superclass? If the only thing that changes is the initialization, and none of the data or later behavior, could you just add parameters to the constructor to control that initialization?