How to maintain initialization of struct as members are added? [closed] - c++

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I have a question that is sort of a follow up to this:
Initializing default values in a struct
I've got a struct that's already got 17 bools, and a clear() method that sets them all to false. It's a long term project; the code could still be in use years from now and get added to. Is there a way to initialize all members that will extend automatically, so that someone adding new members to the struct doesn't need to remember to add them to the clear() method (other than a comment saying "please don't forget")?
This code base is not C++11 at this time, so I don't think I can initialize in the declaration.
The code is like this:
typedef struct {
bool doThingA;
bool doThingB;
bool doThingC;
bool doThingD;
// etc for several more bools
void clear() {
doThingA = false;
doThingB = false;
doThingC = false;
doThingD = false;
// etc...
}
} EnableFlags;

struct EnableFlags {
bool doThingA;
bool doThingB;
bool doThingC;
bool doThingD;
// etc for several more bools
void clear() {
*this = EnableFlags();
}
};
This will create a temporary with all members set to zero and then make *this a copy of it. So it sets all the members to zero, no matter how many there are.
This assumes that you haven't defined a default constructor that does something other than set all the flags to false. If you have no user-defined constructors then that assumption holds.
Since C++11 it's even simpler:
void clear() {
*this = {};
}

One option is to use a static assertion about the size of the structure inside the clear function.
First determine the current size of the struct. Let's say it's 68. Then, add this:
void clear()
{
BOOST_STATIC_ASSERT(sizeof(EnableFlags) == 68 && "You seem to have added a data member. Clear it before changing the number 68 to match current struct size!!");
// the rest as before ...
}
I've used Boost's static assertion macro, but you can use any other one you want, or roll out your own.
With such an assertion, the code will fail to compile when the size of the structure changes. It's not a catch-all solution, but does provide a safeguard.

Just use objetcs.
So you can use a 'for' loop to check in a std::vector if their values are false or true.
So you don't have your futurs co-workers put the "false" value each time they create a new boolean variable.
Structures are inapropriates here.

Related

How can I invoke initialization code from each call site of a function before main() is called? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 days ago.
Improve this question
I want to have a key-value config parameter system in my large application. I want to optimize the simplicity of introducing new config parameters.
But I need to be able to know the complete set of all config parameters declared anywhere in the code, even if the call sites utilizing some parameters are never executed. This capability is needed so that, for example, I can dump out a complete config file so that the user can then edit the config file and run the program again to change config params to non-default values.
So at the call site I want code that looks as close to this as possible:
bool isBlue = getConfigParam("isBlue", true); // The parameter "isBlue" will have a default value of true, but may have been overridden when the config file was loaded.
So the implementation of getConfigParam could insert "isBlue" into the parameter database if it wasn't already in there. But this approach doesn't create the whole list of parameters before main() is called, so the config file can't fully be dumped.
What if getConfigParam() were a macro? What could be in the macro that invokes code before main()?
Some other questions deal with calling code before main(), like this one: Call a function before main
But they all involve declaring a variable at file scope. I want to do it inside a function.
In addition to addressing this precise question, if there are other great ways to do a key-value config database in C++ you could put those in the comments. Thanks in advance.
Something similar is possible.
#include <map>
#include <string>
#include <iostream>
If you use an enum or another similar type for the settings name.
enum class setting_key {
isBlue
};
You can define a getConfigParam that takes the setting name and default value as template arguments.
template <setting_key key, bool value>
struct getConfigParam {
static bool default_value;
operator bool (){
// if (read from config)
// return other value;
return default_value;
}
};
Then create a map of default values and insert into it.
auto& defaults() {
static std::map<setting_key, bool> ret;
return ret;
}
template <setting_key key, bool value>
bool getConfigParam<key, value>::default_value = (
defaults().insert({key, value}),
value
);
That map of defaults gets initialized and inserted into before main or any other function gets called.
void f() {
bool isBlue = getConfigParam<setting_key::isBlue, true>();
}
int main() {
std::cout << "isBlue: " << defaults()[setting_key::isBlue] << "\n";
f();
}

Best C++ practice for retrieving variables from config files [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
The use case is quite common: I have a few variables that should be accessible globally (by various classes) and initialized from a configuration file. I can't decide the best way to do this.
Options struct is owned by someone and passed around:
struct Opts {
int op1;
double op2;
};
int main() {
Opts o = {3, 0.5};
// Pass this around as const reference, or potentially copying
return 0;
}
Use static vars for some Options struct.
struct Opts {
inline static int op1;
inline static double op2;
};
int main() {
Opts::op1 = 3;
Opts::op2 = 0.5;
// No passing around, but use Opts::op1 instead
return 0;
}
Use static vars, but sorta differently (not really).
struct Opts {
static int op1;
static double op2;
};
int Opts::op1;
double Opts::op2;
int main() {
Opts::op1 = 3;
Opts::op2 = 0.5;
// No passing around, but use Opts::op1 instead
return 0;
}
What should I actually do here? I thought the best case would be static const vars to make sure no one changes these, but the values can only be obtained from some file (so seems like it has to be run time instead of compile time), even though they won't change at after initializing.
I could make it const refs if I don't make it static, but that just forces me to pass this around among many classes. I also wanted the class that owns these options to be different from the class that parses them. This would just be even uglier with either moving unique_ptr or copying.
Is there a way to get best of both worlds:
not having to pass things around excessively (hence the semantics of "static")
making sure that these can't be modified after initialization, at least indicating that is the case (hence the semantics of "const")?
I commonly use a singleton Class. A config object is instantiated at startup time, and it reads the content of the file. It contains "getters" which return the values to you, and it might also contain "setters" which allow those values to be changed – in which case it also rewrites the underlying file. The settings file is simply how this object "persists" itself from one run to the next.
The object is also responsible for checking the contents of the settings to ensure that they are proper. If someone edits the file incorrectly, the object is going to throw a meaningful exception. So, if it doesn't do that, you know the settings file is good. The "setters" are equally suspicious: if some other part of the program tries to store an incorrect value, the object will catch the attempt and throw an exception.

error: no matching function for call to Constructor with NULL as argument? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I get the following error when I try to initialize a Team in main() doing:
Team gt(NULL);
error: no matching function for call to 'Team::Team(NULL)'
I'm unsure of how to go about this, as its a test case, so I can't change it.
I have other subclasses of Team, but I'm not sure how to go about actually initializing a Team with NULL as the parameter?
Here is my Team class:
class Team
{
public:
// Each team has a pointer to the next team to forward to
// by default, a team is inactive
Team();
// can handle this?
virtual bool CanHandle(const Ticket &t) const;
// handle the ticket; if handled, return true; otherwise, return false
virtual bool Handle(const Ticket &t);
// Set the team to be active (f=true) or inactive (if f=false)
void SetActive(bool f) {active = f;};
// Is the team active?
bool IsActive() const {return active;};
private:
bool active = false;
Team next_team;
};
EDIT: I forgot to include that I've tried having a constructor with Team(Team *p) but this leads to an "undefined reference to vtable" error. Additionally, its a class representing a chain of responsibility, so it will point to another Team object or NULL.
Since you say Team represents a NULL-terminated chain of Team objects, you need a linked-list of Team* pointers, where the last pointer in the chain is NULL.
Try something more like this:
class Team
{
public:
// Each team has a pointer to the next team to forward to
// by default, a team is inactive
Team() = default;
Team(Team *t) : next_team(t) {}
...
private:
...
Team *next_team = nullptr;
};
Now Team gt(NULL); will work, as will Team gt(nullptr); and even Team gt;
The correct way to default initialize an object is to just Type obj;. In your case, that would look like Team gt;. That calls your default constructor.
If you actually need to initialize a Team with a pointer, you need to write a constructor that can take a pointer, and then use nullptr and forget that NULL was ever a thing.
Your Team should also be just a Team. I see you trying to make it a Team and a list. That's a horrible idea.

Would this be considered bad programming practice? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I had a situation where I wanted to use a default paramenter for a reference in a VERY large legacy codebase for a fix.
static bool _defaultValue = false;
bool SomeFunction(const SomeComplexObject& iObj, bool& isSomeVal = _defaultValue )
{
// ... code
}
My issue is with using a static variable inside a namespace just dangling there by itself.
This code is going to be reviewed before being shipped but I'm unsure if it would be considered bad practice to have a dangling static variable like that.
Without the variable you can't have a default value for a reference. My options are very limited to make other changes to get the desired effect.
Would this be considered "hacky unprofessional coding"?
My suggestion would be:
Remove the global variable.
Don't use a default value for the reference argument.
Create a function overload that has only one argument.
Call the first function from the second function.
bool SomeFunction(const SomeComplexObject& iObj, bool& isSomeVal)
{
// ... code
}
bool SomeFunction(const SomeComplexObject& iObj)
{
bool dummy;
return SomeFunction(iObj, dummy);
}
Client code can call whichever function is appropriate in their context.

C++ Reference Variable [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
How to use 'reference variables' in C++ classes?
I have the following code that I want to put into a class: (note KinectCV&)
KinectCV& kinect = freenect.createDevice(0);
kinect.some_init_functions();
while(condition) {
// getting frames from kinect and processing
kinect.some_processing_functions();
}
kinect.some_stopping_functions();
I'm trying to make a class and separate init, process and stop functions:
class MyKinect {
public:
KinectCV kinect;
void init(){
/* I cannot use the '& kinect = freenect.createDevice(0);' syntax, help me in this */
}
void process(){
kinect.some_processing_functions();
}
void stop(){
kinect.some_stopping_functions();
}
}
I cannot use the '& kinect = freenect.createDevice(0)
That is right, you cannot assign references; once initialized, they refer to the same object forever. What looks like an assignment in your code that works
KinectCV& kinect = freenect.createDevice(0);
is not an assignment, it's initialization. It can be rewritten using the initialization syntax instead of the assignment syntax, like this:
KinectCV& kinect(freenect.createDevice(0));
The reason behind it is that in C++ all initialization must happen in the constructor, not in a "designated initialization function". C++ has no idea that init is your initialization function; all it knows is that once the constructor is over, the object must be in a consistent state, included with all the references that it might hold.
Moving the initialization code into MyKinect's constructor will fix the problem:
class MyKinect {
public:
KinectCV kinect;
MyKinect() : kinect(freenect.createDevice(0)) {
}
}