I'm using the Qt framework to create a ui for my business logic.
The class responsible for building the ui provides several methods which, step by step, initialize the ui elements, layout them, group them and, finally, format (i.e. void MyUi::init3_formatUiElements()) them.
Naturally, some ui elements need numerous layout settings set, so this method might look like
void MyUi::init3_formatUiElements() {
_spinBox_distance->setMinimum(0.0);
_spinBox_distance->setMaximum(10.0);
_spinBox_distance->setSingleStep(0.5);
_spinBox_distance->setSuffix(" meters");
//...
//same for other widgets
return;
}
Objects like QDoubleSpinBox* _spinBox_distance are member fields of the MyUi class.
I would like to have a "temporary alias" for _spinBox_distance, in that the above method body simplifies to
void MyUi::init3_formatUiElements() {
//create alias x for _spinBox_distance here
x->setMinimum(0.0);
x->setMaximum(10.0);
x->setSingleStep(0.5);
x->setSuffix(" meters");
//...
//free alias x here
//same for other widgets: create alias x for next widget
//...
//free alias x here
return;
}
This would speed up the typing process and would make code fragments more copy/paste-able, especially for ui elements of a similar type.
Apart from scoping each block in curly braces
{ QDoubleSpinBox*& x = _spinBox_distance;
x->setMinimum(0.0);
//...
}
{ QLabel*& x = _label_someOtherWidget;
//...
}
is there an elegant way to achieve this?
I tried the above syntax without scoping, but destructing x then of course leads to destruction of the underlying widget.
Maybe
QDoubleSpinBox** x = new QDoubleSpinBox*;
x = &_spinBox_distance;
(*x)->setMinimum(0.0);
//...
delete x;
but that doesn't make things much more type-easy (three extra lines, pointers to pointers, (*x))... :D
EDIT: This one does not work as after delete x, can't be redeclared another type.
What about using a macro ?
#define Set(argument) _spinBox_distance->set##argument
and
Set(Minimum(0.0));
Set(Maximum(10.0));
Set(SingleStep(0.5));
Set(Suffix(" meters"));
Or
#define Set(Argument, Value) _spinBox_distance->set##argument(Value)
Set(Minimum, 0.0);
Set(Maximum, 10.0);
Set(SingleStep, 0.5);
Set(Suffix, " meters");
Collecting the fundamental conceptual thoughts about the problem in question from the comments section, I may post the syntactical/technical answer to the question. This approach, without a doubt, should not be chosen in any kind of "complex" situation (or rather not at all).
bad coding style:
same name for different things
name which doesn't tell you anything about the object
move repeated code to dedicated functions, which...
may specialize on several ui types
are template functions
...
in case of Qt: Use Qt Designer.
...
{ auto x = _spinBox_distance;
x->setMinimum(0.0);
//...
}
{ auto x = _label_someOtherWidget;
//...
}
will do the trick.
I think your code looks fine as it is, I find it much more useful to have the code be easy to read/understand than it is to have the code be easy to write. Remember that you write the code once, then have to read it many times afterwards.
In cases like this I make it easier to write with good old (and oft blamed for mistakes) copy and paste. Grab _spinBox_distance->set and just paste, finish the line, paste, finish the line, etc...
If, however, you find yourself writing those 4 setters in a row over and over again, then put them in 1 function that takes in the 4 parameters.
void SetParameters(QDoubleSpinBox* spinBox_distance, double min, double max, double step, std::string suffix)
{
//the setters
}
Related
I have looked into this, but it's not what I wanted: Convert string to variable name or variable type
I have code that reads an ini file, stores data in a QHash table, and checks the values of the hash key, (see below) if a value is "1" it's added to World.
Code Examples:
World theWorld;
AgentMove AgentMovement(&theWorld);
if(rules.value("AgentMovement") == "1")
theWorld.addRule(&AgentMovement);
INI file:
AgentMovement=1
What I want to do is, dynamically read from the INI file and set a reference to a hard coded variable.
for(int j = 0; j < ck.size(); j++)
if(rules.value(ck[j]) == "1")
theWorld.addRule("&" + ck[j]);
^
= &AgentMovement
How would you make a string into a reference as noted above?
This is a common theme in programming: A value which can only be one of a set (could be an enum, one of a finite set of ints, or a set of possible string values, or even a number of buttons in a GUI) is used as a criteria to perform some kind of action. The simplistic approach is to use a switch (for atomic types) or an if/else chain for complex types. That is what you are currently doing, and there is nothing wrong with it as such:
if(rules.value(ck[j]) == "1") theWorld.addRule(&AgentMovement);
else if(rules.value(ck[j]) == "2") theWorld.addRule(&AgentEat);
else if(rules.value(ck[j]) == "3") theWorld.addRule(&AgentSleep);
// etc.
else error("internal error: weird rules value %s\n", rules.value(ck[j]));
The main advantages of this pattern are in my experience that it is crystal clear: anybody, including you in a year, understands immediately what's going on and can see immediately which criteria leads to which action. It is also trivial to debug which can be a surprising advantage: You can break at a specific action, and only at that action.
The main disadvantage is maintainability. If the same criteria (enum or whatever) is used to switch between different things in various places, all these places have to be maintained, for example when a new enum value is added. An action may come with a sound, an icon, a state change, a log message, and so on. If these do not happen at the same time (in the same switch), you'll end up switching multiple times over the action enum (or if/then/else over the string values). In that case it's better to bundle all information connected to an action in a data structure and put the structures in a map/hash table with the actions as keys. All the switches collapse to single calls. The compile-time initialization of such a map could look like this:
struct ActionDataT { Rule rule; Icon icon; Sound sound; };
map<string, AcionDataT> actionMap
= {
{"1", {AgentMovement, moveIcon, moveSound} }
{"2", {AgentEat, eatIcon, eatSound } } ,
//
};
The usage would be like
for(int j = 0; j < ck.size(); j++)
theWorld.addRule(actionMap[rules.value(ck[j])].rule);
And elsewhere, for example:
if(actionFinished(action)) removeIcon(actionMap[action].icon);
This is fairly elegant. It demonstrates two principles of software design: 1. "All problems in computer science can be solved by another level of indirection" (David Wheeler), and 2. There is often a choice between more data or more code. The simplistic approach is code-oriented, the map approach is data oriented.
The data-centrist approach is indispensable if switches occur in more than one situation, because coding them out each time would be a maintenance nightmare.
Note that with the data-centrist approach none of the places where an action is used has to be touched when a new action is added. This is essential. The mechanism resembles (in principle and implementation, actually) the call of a virtual member function. The calling code doesn't know and isn't really interested in what is actually done. Responsibility is transferred to the object. The calling code may perform actions later in the life cycle of a program which didn't exist when it was written. By contrast, compare it to a program with many explicit switches where every single use must be examined when an action is added.
The indirection involved in the data-centrist approach is its disadvantage though, and the only problem which cannot be solved by another level of indirection, as Wheeler remarked. The code becomes more abstract and hence less obvious and harder to debug.
You have to provide the mapping from the names to the object by yourself. I would wrap it into a class, something like this:
template <typename T>
struct ObjectMap {
void addObject(std::string name,T* obj){
m[name] = obj;
}
T& getRef(std::string name) const {
auto x = m.find(name);
if (x != m.end() ) { return *(x->second);}
else { return dummy; }
}
private:
std::map<std::string,T*> m;
T dummy;
}
The problem with this approach is that you have to decide what to do if an object is requested that is actually not in the map. A reference always has to reference something (in contrast to a pointer that can be 0). I decided to return the reference to a dummy object. However, you might want to consider to use pointers instead of references. Another option might be to throw an error in case the object is not in the map.
I am making an application in C++, and it requires a config file that will be read and interpreted on launch. It will contain things such as:
Module1=true
Now, my original plan was to store it all in variables and simply have
If(module1) {
DO_STUFF();
}
However this seems wasteful as it would be checking constantly for a value that would never change. Any ideas?
Optimize the code, only if you find a bottleneck with a profiler. Branch prediction should do its thing here, module1 never changes, so if you call it in a loop, even, there shouldn't be a noticeable performance loss.
If you want to experiment, you can branch once, and make a pointer point to the right function:
using func_ptr = void (*)();
func_ptr p = [](){};
if(module1)
p = DO_STUFF;
while(...)
p();
But this is just something to profile, look at the assembly...
There are also slower, but comfortable ways you could be storing the configuration, e.g. in an array with enumerated indexes, or a map. If I were to get some value in a loop, I'd do:
auto module1 = modules[MODULE1]; // array and enumeration
//auto module1 = modules.at("module1"); // map and string
while(...)
{
if(module1)
DO_STUFF;
...
}
So I'd end up with what you already have.
performance wise a boolean check is no problem, except you start doing it millions or billions of times. Maybe you can start merging code which belongs to module1, but other than that you'd have to check for it like you currently do
This really isn't an issue. If your program requires that Module1 should be true then let it check the value and continue on. It wont affect your performance unless it is being checked too many times.
One thing you could do is make an inline function if it being checked too many times. However, you will have to make sure the function shouldnt be too big otherwise it will be a bigger bottleneck
Sorry guys, didn't spot this when I looked it up:
MDSN
So I check the boolean once on launch and then I don't need to anymore as only the correct functions are launched.
Depending on how your program is set up and how the variables change the behaviour of the code you might be able to use function pointers:
if(Module1 == true)
{
std::function<void(int)> DoStuff = Module1Stuff;
}
And then later:
while(true)
{
DoStuff(ImportantVariable);
}
See http://en.cppreference.com/w/cpp/utility/functional/function for further reference.
Not that I think it'll help all that much but it's an alternative to try out at least.
This can be solved if you know the all use cases of the values you check. For example, if you've read your config file and module1 is true - you do one thing, if it is false - another. Let's start with example:
class ConfigFileWorker {
public:
virtual void run() = 0;
};
class WithModule1Worker {
public:
void run() final override {
// do stuff as if your `Module1` is true
}
};
class WithoutModule1Worker {
public:
void run() final override {
// do stuff as if your `Module1` is false
}
};
int main() {
std::unique_ptr<ConfigFileWorker> worker;
const bool Module1 = read_config_file(file, "Module1");
if (Module1) { // you check this only once during launch and just use `worker` all the time after
worker.reset(new WithModule1Worker);
} else {
worker.reset(new WithoutModule1Worker);
}
// here and after just use the pointer with `run()` - then you will not need to check the variable all the time, you'll just perform action.
}
So you have predefined behaviour for 2 cases (true and false) and just create an object of one of them during parsing the config file on launch. This is java-like code, but of course you may use function pointers, std::function and other abstractions instead of a base class, however, base class-option has more flexibility in my opinion.
I've found a question sorta similar to this one, though put in a more complex way than I think I require (received a -2 for question score). Hopefully this will be easier to follow.
The general gist of things is the two classes involved are GUI and Player (I've had the same problem elsewhere with other classes, but if I can understand why this one isn't working, it should apply to the rest).
GUI includes "Player.h". The class Player has a public boolean variable 'hasBall'; When a 'Player' is passed into a function Pass() and the boolean value changed, it seems that it is only a temp object thus isn't updating the object being passed itself. See code below:
This works fine, boolean values for Plyr1A and Plyr2A (defined in Gui.h) are changed and preserved
Plyr1A.hasBall = false;
Plyr2A.hasBall = true;
However boolean values for Plyr1A and Plyr2A remain the same with this.
Pass(Plyr1A,Plyr2A); //Boolean values for Plyr1A and Plyr2A remain the same with this.
void GUI::Pass(Player passer, Player receiver) {
passer.hasBall = false;
receiver.hasBall = true;
}
If anyone could explain to me why this occurs I'd be rather thankful! If there is any extra information needed please let me know.
Cheers :)
Your function makes a copy of the arguments (they are passed by value), then changes the copy, not the "original" objects(in the body of the function).
You should change it to take pointers or references, for example:
//-------------------v---------------v <---these are references
void GUI::Pass(Player& passer, Player& receiver) {
Of course, you should change the declaration, too.
Use references to pass your objects.
Consider this function:
void someFunction (int j)
{
j = 8;
}
And say we call it like this:
someFunction (3);
Are you thinking the assignment in someFunction somehow makes that 3 become an 8? Your expectation makes no sense. Without some kind of special arrangement, it cannot be that an assignment inside a function changes values in the caller.
I am very new to programming and am confused about what void does, I know that when you put void in front of a function it means that "it returns nothing" but if the function returns nothing then what is the point of writing the function?? Anyway, I got this question on my homework and am trying to answer it but need some help with the general concept along with it. any help would be great, and please try to avoid technical lingo, I'm a serious newb here.
What does this function accomplish?
void add2numbers(double a, double b)
{
double sum;
sum = a + b;
}
void ReturnsNothing()
{
cout << "Hello!";
}
As you can see, this function returns nothing, but that doesn't mean the function does nothing.
A function is nothing more than a refactoring of the code to put commonly-used routines together. If I'm printing "Hello" often, I put the code that prints "Hello" in a function. If I'm calculating the sum of two numbers, I'll put the code to do that and return the result in a function. It's all about what you want.
There are loads of reasons to have void functions, some of these are having 'non pure' side effects:
int i=9;
void f() {
++i;
}
In this case i could be global or a class data member.
The other is observable effects
void f() {
std::cout <<"hello world" << std::endl;
}
A void function may act on a reference or pointer value.
void f(int& i) {
++i;
}
It could also throw, although don't do this for flow control.
void f() {
while(is_not_broke()) {
//...
}
throw std::exception(); //it broke
}
The purpose of a void function is to achieve a side effect (e.g., modify a reference parameter or a global variable, perform system calls such as I/O, etc.), not return a value.
The use of the term function in the context of C/C++ is rather confusing, because it disagrees wiht the mathematical concept of a function as "something returning a value". What C/C++ calls functions returning void corresponds to the concept of a procedure in other languages.
The major difference between a function and a procedure is that a function call is an expression, while a procedure call is a statement While functions are invoked for their return value, procedures are invoked for their side effects (such as producing output, changing state, and so on).
A function with void return value can be useful for its side effects. For example consider the standard library function exit:
void exit(int status)
This function doesn't return any value to you, but it's still useful for its side-effect of terminating the process.
You are on the right lines - the function doesn't accomplish anything, because it calculates something but that something then gets thrown away.
Functions returning void can be useful because they can have "side effects". This means something happens that isn't an input or output of the function. For example it could write to a file, or send an email.
Function is a bit of a missnomer in this case; perhaps calling it a method is better. You can call a method on an object to change its state, i.e. the values of it's fields (or properties). So you might have an object with properites for x and y coordinates and a method called Move which takes parameters xDelta and yDelta.
Calling Move with 2, 3 will cause 2 to be added to your X property and 3 to be added to your Y property. So the state of the object has changed and it wouldn't have made musch sense for Move to have returned a value.
That function achieves nothing - but if you had written
void add2numbers(double a, double b, double &sum)
{
sum = a + b;
}
It would give you the sum, whether it's easier to return a value or use a parameter depends on the function
Typically you would use a parameter if there are multiple results but suppose you had a maths routine where an answer might not be possible.
bool sqrt(double value, double &answer)
{
if value < 0.0 ) {
return false;
} else {
answer = real_sqrt_function(value);
return true;
}
}
I currently use a visualization library called VTK. I normally write void functions to update some part of the graphics that are displayed to the screen. I also use void functions to handle GUI interaction within Qt. For example, if you click a button, some text gets updated on the GUI.
You're completely right: calculating a function that returns nothing is meaningless – if you're talking about mathematical functions. But like with many mathematical concepts, "functions" are in many programming languages only related to mathematical functions, but behave more or less subtly different.
I believe it's good to explain it with a language that does not get it wrong: one such language is Haskell. That's a purely functional language which means a Haskell function is also a mathematical function. Indeed you can write Haskell functions much more mathematical-styled, e.g.
my_tan(x) = sin(x)/cos(x) -- or (preferred): tan' x = sin x / cos x
than in C++
double my_tan(double x) { return sin(x)/cos(x); }
However, in computer programs you don't just want to calculate functions, do you? You also want to get stuff done, like displaying something on your screen, sending data over the network, reading values from sensors etc.. In Haskell, things like these are well separated from pure functions, they all act in the so-called IO monad. For instance, the function putStrLn, which prints a line of characters, has type String -> IO(). Meaning, it takes a String as its argument and returns an IO action which prints out that string when invoked from the main function, and nothing else (the () parens are roughly what's void in C++).
This way of doing IO has many benefits, but most programming languages are more sloppy: they allow all functions to do IO, and also to change the internal state of your program. So in C++, you could simply have a function void putStrLn(std::string), which also "returns" an IO action that prints the string and nothing else, but does not explicitly tell you so. The benefit is that you don't need to tie multiple knots in your brain when thinking about what the IO monad actually is (it's rather roundabout). Also, many algorithms can be implemented to run faster if you have the ability to actually tell the machine "do this sequence of processes, now!" rather than just asking for the result of some computation in the IO monad.
I have a lot of legacy code using macro of the form:
#define FXX(x) pField->GetValue(x)
The macro forces variable pField be in the scope:
.....
FIELD *pField = ....
.....
int i = FXX(3);
int j = FXX(5);
Is there way to replace the macro, without touching user code?
Since FXX(x) has a function invocation style, I thought about inline function or something similar.
UPD:
People just used to the macro, and I want to remain it as is.
How about using a find & replace function in your favorite editor...I think it would work fine in the example you gave in your question. Replace FXX with pField->GetValue and then remove the #define line
What is pField (besides a fine example of the abomination that is Systems Hungarian)? If, by chance, it's a global variable or a singleton or something that we only need one of, we could do a nifty trick like this:
int FFX(int x)
{
static FIELD *pField = ...; // remove this line if pField is global
return pField->GetValue(x);
}
Change the int types to whatever types you need it to operate on, or even a template if you need it to support multiple types.
Another alternative, suggested by #epatel, is to use your favorite text editor's find-and-replace and just change all the FFX(x) lines to pField->GetValue(x), thus eliminating the macro invokation in your code. If you want to keep a function invokation, you culd change FFX(x) to FFX(pField, x) and change the macro to take two arguments (or change it to a function that takes two arguments). But you might as well just take out the macro at that point.
A third alternative, is not to fix that which is not broken. The macro isn't particularly nice, but you may introduce greater problems by trying to remove it. Macros aren't the spawn of Satan (though this one has at least a few relatives in hell).
What you need is a function that relies on a variable being defined. The only way to do that is to declare that variable in the same scope as the function. But then your function would use that one instead of the one declared from where your function is called.
So I'm fairly confident it can't be done.
Well, if you can put this function definition where pField is already in scope:
int FXX(int x) { return pField->GetValue(x); }
Otherwise, there's no way to get pField into the the function without affecting existing code.
This may be a case where using the macro is the best alternative. Macros may be evil, but they are sometimes necessary. See http://www.parashift.com/c++-faq-lite/big-picture.html#faq-6.15
I would leave it as it is, but just for the sake of discussion, and depending on what parts of the code are 'untouchable' you could define a functor that takes a pField and initialize after the variable is created in the same scope:
class FFX_t {
FFX_t( FIELD * pField ) : field_(pField) {}
int operator()( int index ) {
return field_->GetValue( index );
}
private:
FIELD *field_;
};
// usage:
void f() {
FIELD * pField = //...
FFX_t FFX(pField); // added after pField construction
// ...
int a = FFX(5);
}
But I insist in that changing working code for the sake of it when it will not really add any value is useless.